V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
工单节点使用指南
• 请用平和的语言准确描述你所遇到的问题
• 厂商的技术支持和你一样也是有喜怒哀乐的普通人类,尊重是相互的
• 如果是关于 V2EX 本身的问题反馈,请使用 反馈 节点
xiangyuecn
V2EX  ›  全球工单系统

老是有 自作聪明的 程序员在 会随时间变化的地方 用手写白名单 还不更新

  •  
  •   xiangyuecn · 2019-01-16 13:25:22 +08:00 · 12120 次点击
    这是一个创建于 2172 天前的主题,其中的信息可能已经有所发展或是发生改变。

    见得多的: 编写代码那个时代存在的手机号段正则表达式(人才)。。。

    不能忍的: 编写代码那个时代存在的顶级域名正则表达式(还不全)。。。

    最近遇到个扫码工具不认一个 url,小众顶级域名,改成.com 这个顶级域名就可以就可以认。不难猜想,写这个代码的程序员如此的牛逼,找了一段自认为可以降服一切的域名下 url 的匹配方式。。让每年可能会出那个个把子的顶级域名情何以堪?

    昨天在微博上搞微博登录,发现应用信息里面可以填安全域名,我的一个小众顶级域名后缀域名死活不认,工信部都认了。。。改成 com 就这种问题,今天研究了一下他们家代码,真是写的一手好代码呀,微博前端团队+后端团队,估计前后端这个限制代码都是同一个人写的吧,绕都绕不过。。。人才

    解决办法:简化规则,皆大欢喜~ 手机号,url 大部分地方都可以使用最简化的正则表达式来判断。

    随手写一个域名判断:/^([\w-]+.)+(\w+)$/,应该能适用大部分地方,小部分除外,新出顶级域名还不用更新。 随手写一个手机号判断:/^1\d{10}$/,应该能适用大部分地方,小部分除外,新出号段还不用更新。

    另:记得 chrome 里面使用的是一个地方维护着的顶级域名列表,这种需要判断顶级域名的地方并且需要显示自己牛逼的地方,不学学?

    主要呼叫微博吧,其他的就算了,开放平台->我的应用->基本信息->安全域名

    88 条回复    2019-01-17 20:31:07 +08:00
    nervdy
        1
    nervdy  
       2019-01-16 13:34:25 +08:00
    你的随手写可能会留下更大的坑
    drydiy
        2
    drydiy  
       2019-01-16 13:40:23 +08:00
    你这随手写思考过??
    这不严谨的态度明显不对。
    xiangyuecn
        3
    xiangyuecn  
    OP
       2019-01-16 13:41:50 +08:00
    @nervdy 我觉得微博这里就算不验证格式,随便写 abcd,也不会对业务逻辑产生任何影响,也不会有安全问题,你能用 abcd 这个域名访问微博接口,说明你已经持有了 abcd 这个域名,虽然这个域名看起来不合规。

    留坑也比不能用好更好些吧~
    frye
        4
    frye  
       2019-01-16 13:42:57 +08:00
    处于安全的角度,我觉得微博的做法没错
    xiangyuecn
        5
    xiangyuecn  
    OP
       2019-01-16 13:43:36 +08:00
    @drydiy 大部分场合不需要这种多此一举的严谨,你觉得呢。尤其是这个扫码的,想想就怪怪的
    flyingghost
        6
    flyingghost  
       2019-01-16 13:44:52 +08:00   ❤️ 1
    宽标准=前瞻性=漏洞百出的校验?
    严标准=基于现实=无法适应变化?
    这两条路都不是什么好路子。
    好路子难道不是
    基于当前的严标准 + 配置化等易扩展易维护的结构 + 最重要的时时刻刻维护更新 嘛?
    xiangyuecn
        7
    xiangyuecn  
    OP
       2019-01-16 13:47:50 +08:00
    @frye 这是导致不能用的安全。。

    这个地方重要的应该是判断书写是否错误,而不是用来判断域名有效性。如果要判断输入有效性,应该判断这个域名的有效性( DNS 解析、whois 之类的),而非特定格式。
    xiangyuecn
        8
    xiangyuecn  
    OP
       2019-01-16 13:49:21 +08:00
    @flyingghost 难在维护更新,要是他们会更新,也就不会导致这种问题。
    sagaxu
        9
    sagaxu  
       2019-01-16 13:49:59 +08:00 via Android   ❤️ 9
    小众域名客户的商业价值低,爱用不用
    xiangyuecn
        10
    xiangyuecn  
    OP
       2019-01-16 13:51:50 +08:00
    @sagaxu 无言以对,事实如此呀,记得前几年这个域名注册商哪里注册好了,然后自己很多地方自己都不支持这个域名,无奈~
    reus
        11
    reus  
       2019-01-16 13:56:51 +08:00
    程序员才懒得做这种事情,一般是傻逼产品的锅
    gesse
        12
    gesse  
       2019-01-16 13:58:48 +08:00
    你怎么知道人家是手写、固定死了的? 现在很多 JS 都是配置然后生成的
    xiangyuecn
        13
    xiangyuecn  
    OP
       2019-01-16 14:01:08 +08:00
    想到一个绝佳的例子:
    手机号,不会错的地方不校验也不会错,会错的地方怎么校验都可能出错。

    注册:手机号要收验证码这种,就算不校验手机号格式,也 100%不会出错。
    收获地址:手机号随便填大部分好像不会验证真实性,这个地方就算校验了格式,还是可能输错,而且还发货了,快递小哥找不到人这种。。
    xiangyuecn
        14
    xiangyuecn  
    OP
       2019-01-16 14:04:13 +08:00
    @gesse 哈哈,神奇的在于配置是手写固定死的,还不更新,虽然经过 build 这个伪动态过程,按这个逻辑往上盘
    geelaw
        15
    geelaw  
       2019-01-16 14:10:34 +08:00 via iPhone
    🙄您连 dot 都忘了转义
    xiangyuecn
        16
    xiangyuecn  
    OP
       2019-01-16 14:12:23 +08:00
    @geelaw 哦,改不了啦,被你发现了~
    iNaru
        17
    iNaru  
       2019-01-16 14:17:50 +08:00   ❤️ 2
    https://www.publicsuffix.org/learn/

    Some people use the PSL to determine what is a valid domain name and what isn't. This is dangerous, particularly in these days where new gTLDs are arriving at a rapid pace, if your software does not regularly receive PSL updates, because it will erroneously think new gTLDs are not valid. The DNS is the proper source for this information. If you must use it for this purpose, please do not bake static copies of the PSL into your software with no update mechanism.
    wysnylc
        18
    wysnylc  
       2019-01-16 14:21:19 +08:00
    您可真不自作聪明
    lhx2008
        19
    lhx2008  
       2019-01-16 14:22:24 +08:00
    QQ 邮箱还只能发几个后缀的邮箱呢,V2EX 也有一票域名不能识别
    alvin666
        20
    alvin666  
       2019-01-16 14:23:46 +08:00 via Android
    手机号重置全是这样写死的,199 刚出来的时候哪里都不能充值
    zsdroid
        21
    zsdroid  
       2019-01-16 14:28:39 +08:00   ❤️ 4
    老是有 自作聪明的 程序员在 需要验证的地方说不要验证
    iwtbauh
        22
    iwtbauh  
       2019-01-16 14:35:27 +08:00 via Android
    这个问题不是“不需要验证”,而是“验证的方式不对”。

    当然需要验证,但是把收集后戳作为知识塞入代码明显是不对的。而且也是违反互联网标准的。DNS 不就是为了解决这个诞生的吗。
    zwh2698
        23
    zwh2698  
       2019-01-16 14:39:10 +08:00 via Android
    建议学习安全编码
    daixu
        24
    daixu  
       2019-01-16 15:37:31 +08:00
    这种东西大概率是测试或者产品提出来。然后开发才写死的。关开发的猫猫关系啊。没事谁愿意把这东西写死咯。
    corkspin
        25
    corkspin  
       2019-01-16 15:50:10 +08:00
    @daixu 说得对,产品和测试说 abcd.abcd 不是一个域名,199..不是一个手机号。 楼主那两个正则可比下面的简单太多了。
    xnode
        26
    xnode  
       2019-01-16 16:05:14 +08:00
    ...喷的点不对吧,要喷就喷 新浪不能快速迭代验证
    tianyou666shen
        27
    tianyou666shen  
       2019-01-16 16:18:39 +08:00
    楼主没上过班吗?
    这种业务需求能是程序员定的 ? 没见过一种生物叫做产品吗?
    不晓得这位大佬在哪里高就 是几个人团队的 leader ...
    woodensail
        28
    woodensail  
       2019-01-16 16:24:37 +08:00
    @xiangyuecn
    很多时候安全性是重于可用性的
    woodensail
        29
    woodensail  
       2019-01-16 16:25:14 +08:00
    嗯,我好像回错人了,算了……
    ioven
        30
    ioven  
       2019-01-16 16:30:31 +08:00
    @xiangyuecn 收验证码的手机号不用验证?难道直接发短信?
    xiangyuecn
        31
    xiangyuecn  
    OP
       2019-01-16 16:43:54 +08:00
    @ioven 我说的没这么极端。。。我在 13 楼 说的意思是通过格式验证并不能校验有效性,能简化的尽量简化,就算把正则写出花了,复杂表达式和简单表达式在对安全性上的作用基本属于同一个量级。
    gesse
        32
    gesse  
       2019-01-16 16:54:35 +08:00
    大家都散了吧, 无法沟通。
    zhttty
        33
    zhttty  
       2019-01-16 16:56:58 +08:00   ❤️ 3
    看了你的内容和“随手写”,我觉得楼主就是那种程序员,拿自己举例挺好的,这下子大家都明白什么叫做“自作聪明”了。
    rqzheng2008
        34
    rqzheng2008  
       2019-01-16 16:59:29 +08:00 via Android
    可以,很自作聪明的 lz
    balamiao
        35
    balamiao  
       2019-01-16 17:03:14 +08:00
    楼主够沙雕~
    weixiangzhe
        36
    weixiangzhe  
       2019-01-16 17:11:03 +08:00 via iPhone
    通用正则搞个 cdn 更剩事吧
    xiangyuecn
        37
    xiangyuecn  
    OP
       2019-01-16 17:18:48 +08:00
    #35 这个人就懒得 @ 你了

    @zhttty @rqzheng2008 也许吧,其实我真实那种是自我感觉良好的,随你们怎么说~

    不过如果你们仔细思考一下微博里面的细节,也许会有不同的论断。
    lincanbin
        38
    lincanbin  
       2019-01-16 17:20:57 +08:00
    域名还支持中文域名。
    http://中文.tw
    xiangyuecn
        39
    xiangyuecn  
    OP
       2019-01-16 17:26:58 +08:00
    @lincanbin 嗯,如果要直接支持中文域名,正则会难写好多,不过也许绕一下会简单好多,如果用户的域名带 Unicode 字符,可以填写 Punycode 表示的域名。微博开放平台别说小众顶级域名不支持了,中文域名就更不支持,哈哈,上午我试了下,挺好玩的
    allenhu
        40
    allenhu  
       2019-01-16 18:17:37 +08:00
    没毛病,够用就好,那些奇奇怪怪的域名,可以忽略
    pkoukk
        41
    pkoukk  
       2019-01-16 18:19:42 +08:00
    说不定程序员当初写的挺宽泛的
    然后测试表示:abc.bcd 不是一个有效域名,你程序错了
    firebroo
        42
    firebroo  
       2019-01-16 18:30:14 +08:00 via Android
    你这两个随手真的会产生很多安全问题
    cdwyd
        43
    cdwyd  
       2019-01-16 18:33:00 +08:00 via Android
    v2 也不能识别我的小众域名,狗头
    meizi.lol
    atonku
        44
    atonku  
       2019-01-16 18:50:55 +08:00
    你牛逼行了吧
    xiangyuecn
        45
    xiangyuecn  
    OP
       2019-01-16 18:58:35 +08:00
    @firebroo 有没有比较常见的场景例子?冗长的表达式没有问题,而我这个随手写的会有问题。我想了一下,没有想到哪里会产生比较大的差异,觉得短的有问题的时候,长的可能也会有问题。
    hiboshi
        46
    hiboshi  
       2019-01-16 19:01:14 +08:00
    你为什么选那 千分之一。
    secondwtq
        47
    secondwtq  
       2019-01-16 19:05:05 +08:00
    Firefox 的地址栏现在可以直接搜索,但是只要是 xxx.x 格式的串,都会直接被当成域名尝试解析,然后“找不到服务器”

    导致我想搜一个类似 libpthread.a 之类的单文件名的时候很蛋疼
    autoxbc
        48
    autoxbc  
       2019-01-16 19:42:02 +08:00   ❤️ 3
    你说到某些人的痛处了,他们自然要喷你

    tldjs.parse('xxx.life')

    >>>
    domain "xxx.life"
    hostname "xxx.life"
    isIp false
    isValid true
    publicSuffix "life"
    subdomain ""
    tldExists true

    https://github.com/oncletom/tld.js/
    hellowes
        49
    hellowes  
       2019-01-16 19:54:47 +08:00
    com 域名可以,其他的就不行,我觉得这就很歧视了,纯粹是程序员水平问题,产品怎么干涉的了域名这种东西呢?
    workwonder
        50
    workwonder  
       2019-01-16 20:33:00 +08:00 via Android
    支持楼主
    jimrok
        51
    jimrok  
       2019-01-16 20:40:20 +08:00
    找到他们的 QA,最好的办法就是这个了。
    azh7138m
        52
    azh7138m  
       2019-01-16 20:47:15 +08:00 via Android
    推荐按照 rfc1738 和 rfc3986 来做。
    安利一下我的 demo,https://github.com/muzea/parser/blob/master/sample/rfc1738.ts
    多好 :D
    firebroo
        53
    firebroo  
       2019-01-16 21:09:20 +08:00 via Android
    @xiangyuecn 文件上传之类的,最好的方式就是白名单文件后缀,正则和黑名单被绕过可能性很大。实际安全漏洞还需要结合实际情景,千奇白怪的正则导致被绕过的例子网上很多,所有我都是建议用万金油白名单
    xiangyuecn
        54
    xiangyuecn  
    OP
       2019-01-16 21:30:12 +08:00
    @firebroo 你提到的这点和这个帖子说的内容偏离的蛮大,感觉有点跑题了喔 (无奈脸
    ioven
        55
    ioven  
       2019-01-16 22:07:58 +08:00
    @xiangyuecn 同意标题,不同意内容

    白名单没问题,不更新才是大问题
    firebroo
        56
    firebroo  
       2019-01-16 23:01:51 +08:00 via Android
    @xiangyuecn 非要让我意淫出个漏洞吗。。比如域名匹配那个,我服务端截取最后一个.字符到结尾的子字符串填充到一个 1024 字节长度的缓冲期里面做处理,你写的正则没有限制后缀长度就会缓冲区溢出,白名单方式后缀长度可估量,肯定远小于 1024 字节,所以安全。当然这是我意淫的漏洞,线上环境千奇百怪也不是说不可能出现这种。
    applehater
        57
    applehater  
       2019-01-16 23:29:26 +08:00
    公司线上在运行的就有这样的问题
    xiangyuecn
        58
    xiangyuecn  
    OP
       2019-01-16 23:50:26 +08:00
    @firebroo #56 哈哈,这个算。缓冲区这种从来没接触过这么底层的东西,我换成了一维数组来看,不检查边界乱塞数据会导致比空指针还恶心的异常。

    没想到域名检测在什么样常见的场景会出安全问题,我举个稍微偏一点的例子吧,搭边一点点:
    场景:用户提交任意 https? url,服务器端会对这个 url 进行请求,比如远程图片抓取保存到服务器本地。
    问题:如果不检测 url 中的主机名,可能导致内网地址被恶意调用。
    解决办法:提取 url 中的主机名,如果是 ip 结构,判断是不是公网 IP。如果是域名结构,判断是否是 xx.xx 结构(排除 localhost )
    当然这仅仅是发起请求前的一项安全检测。
    Ansonyi
        59
    Ansonyi  
       2019-01-17 02:24:24 +08:00 via iPhone
    百度统计,好多后缀域名不认。
    KasuganoSoras
        60
    KasuganoSoras  
       2019-01-17 02:30:12 +08:00
    这么麻烦,搞个 whois 查询接口不就好了,查一下域名的 whois 信息,就可以判断一个域名是否正确了啊
    怕接口滥用可以限制一下接口的请求频率 + 登录验证
    lincanbin
        61
    lincanbin  
       2019-01-17 02:37:43 +08:00 via Android   ❤️ 7
    事实上我也这么枚举号段。

    因为以前手机号没对号段做限制。
    测试给我提了个 bug,我说这不是 bug,是个为未来考虑的 feature。
    测试不听我说,我就把手机号段做了枚举检验,并且在 commit 里写下了测试的名字,注明是他要求的。

    后来新增了 166、170 号段啥的,导致一些用户无法注册。

    我拉出 commit log,就让测试背锅了。
    KasuganoSoras
        62
    KasuganoSoras  
       2019-01-17 02:47:13 +08:00
    @firebroo 过长的字符串让缓冲区溢出?不存在的
    if(mb_strlen($_POST['domain']) > 80) echo "invalid domain";
    还没见过长度超过 80 的域名

    另外,可以不必使用 whois,直接要求用户添加指定的 dns 解析,然后 dns_get_record 就行啦

    还可以更简单,直接指定要求用户将指定域名前缀解析 A 记录到指定 IP,比如 127.0.0.1,然后用 gethostbyname 获取域名的 A 记录,如果解析成功就说明是有效域名,否则就是无效的,这种方法比查询 whois 更快,原理也和 CA 签发 SSL 证书验证一样。

    我的 QQ 机器人的 ping 功能就是用 dns 判断域名是否有效的,公开丢到一百多个群里随便别人调戏玩耍,至今也没有被玩坏。

    PHP 大法好
    billwsy
        63
    billwsy  
       2019-01-17 06:23:30 +08:00
    "abc.local"这样的域名会不会带来安全隐患,如果服务器正好安装了 mDNS 的话
    flowfire
        64
    flowfire  
       2019-01-17 06:27:30 +08:00 via Android   ❤️ 1
    前段的检验只是方便用户使用,第一时间反馈给用户,后端的校验才是安全校验,很明显,前段应该留一个宽松的标准,准确的校验应该留给后端
    LeoSocks
        65
    LeoSocks  
       2019-01-17 07:10:51 +08:00 via iPhone
    @xiangyuecn 保住大鱼,放过小鱼。意思是,你这样的用户,他不要也罢
    yamedie
        66
    yamedie  
       2019-01-17 07:20:45 +08:00 via Android
    您写的正则我举 2 个反例
    域名:abc.abcdefghijklmnopqrstuvwxyz (后缀不限长度)
    手机号:11012345678 (用座机拨个试试)
    isCyan
        67
    isCyan  
       2019-01-17 07:43:20 +08:00 via Android
    前端简单校验
    后端基于已有数据校验
    手机号可以用 libphonenumber
    域名可以用 public-suffix
    workwonder
        68
    workwonder  
       2019-01-17 07:53:47 +08:00 via Android
    赞同楼主的人没几个,我是其中一个。
    画蛇添足,形容很到位。
    坚持自己的观点,别评论被扭歪了。
    master13
        69
    master13  
       2019-01-17 08:03:36 +08:00
    挖坟一时爽,全家火葬场
    yksoft1ex
        70
    yksoft1ex  
       2019-01-17 08:09:59 +08:00
    我到只是觉得白名单不应该在前端 js 里面验证。
    mytsing520
        71
    mytsing520  
       2019-01-17 08:31:46 +08:00
    程序猿表示:产品的锅我不背
    firebroo
        72
    firebroo  
       2019-01-17 08:45:57 +08:00 via Android   ❤️ 1
    @xiangyuecn 你那个有专业词汇,叫 ssrf~
    @KasuganoSoras 杠精。🤣,解决方法当然有 n 种,我这不是在制造漏洞嘛。
    MrJing1992
        73
    MrJing1992  
       2019-01-17 09:01:58 +08:00
    我们之前手机号验证也是写得无比复杂,后来,工信部加了新号段;又后来,公司业务切入到了海外。于是也改为使用 /^1\d{10}$/了。当然,我们有短信码校验。
    xianxiaobo
        74
    xianxiaobo  
       2019-01-17 09:11:00 +08:00
    某天出了 10 位或者 12 位的手机号,你的正则一样不行,然后就会有人发帖,为什么大家不会把手机号验证写为 20 位以内的数字就行呢?扩展性多好,新出的长度还不用更新
    SakuraKuma
        75
    SakuraKuma  
       2019-01-17 09:23:31 +08:00
    这样写没毛病啊,
    猫并是,他不更新啊。
    而且就算你绕过了前端。
    后端估计也是一样的白名单。
    TingHaiJamiE
        76
    TingHaiJamiE  
       2019-01-17 09:26:28 +08:00
    别的不说,我个人十分赞同楼主手机号验证的方式。1 后面 10 个数字足够。
    xiangyuecn
        77
    xiangyuecn  
    OP
       2019-01-17 09:30:45 +08:00
    @lincanbin #61 第一个测试的锅 真实案例 (〃'▽'〃) 还好准备充足呀
    eliteYang
        78
    eliteYang  
       2019-01-17 09:32:22 +08:00
    因为有一些 sb 产品经理会随时修改需求
    veike
        79
    veike  
       2019-01-17 09:36:05 +08:00
    你这个域名判断,后缀不应该加上字数限制吗,这样更严谨啊。
    一个域名最长的长度为:255 个字节(包括标点符号)。域名名称最长 63 字节,比如 example.com example 部分最长 63 字节。后缀最多也不会超过 20 个字节。
    所以,按照我这个才更严谨。
    murmur
        80
    murmur  
       2019-01-17 09:39:58 +08:00
    楼上的不要喷了
    如果这是其他的公司我会喷楼主
    如果是微博我更相信微博的产品经理 sb
    xiangyuecn
        81
    xiangyuecn  
    OP
       2019-01-17 09:40:49 +08:00
    @xianxiaobo #74 根据我个人对 三大运营商 手机号的理解,几十年来首位 1 都是多余的。。除了增加号段、还没出现过增加位数的先例。如果 1 可以改成 2-9 还有很大的发展空间,就是不知道有什么难点,宁可复用垃圾号码也不增加容量。
    xiangyuecn
        82
    xiangyuecn  
    OP
       2019-01-17 09:46:02 +08:00
    @firebroo #72 原来是 ssrf,怪不得眼熟,想起一个严峻的事情,就是人家提交过来的合法域名格式的 url 也不一定安全,谁知道他会不会把 DNS 记录写成内网地址,看样子水深了不少。。

    不知道简书、掘金发文那里怎么把图片捞过来的?
    xiangyuecn
        83
    xiangyuecn  
    OP
       2019-01-17 09:50:20 +08:00
    @veike #79 本来有两个选择:宽松、严格,现在又加一个:宽松、中等、严格。选择恐惧症,我还是喜欢简单粗暴的,要么就是 True,要么就是 False
    firebroo
        84
    firebroo  
       2019-01-17 10:07:59 +08:00
    @xiangyuecn 限制提交数据为.jpg ,.png 等白名单图片后缀格式的 url,也可以对返回数据做检测,根据前面几个字节判断是不是图片格式,这样即使可以 ssrf,危害也大大减小。单独划一个公网段和内网隔离做爬虫,黑名单内网 ip 段。
    MrUser
        85
    MrUser  
       2019-01-17 10:18:23 +08:00
    这种验证确实很烦人,
    我遇到的类似的情况:有些注册帐号的地方只认常见的邮箱后缀,你填个 [email protected] 非说邮箱不正确,只让填 @gmail.com \ @163.com \ @qq.com 类的
    no1xsyzy
        86
    no1xsyzy  
       2019-01-17 10:52:15 +08:00
    我 126 的邮箱很多国外网站不能注册,说邮箱域名不符合规范……
    国内反而是更清楚地知道存在 126 和 163 这种纯数字一级域,导致兼容性更高……
    Klingon
        87
    Klingon  
       2019-01-17 12:47:22 +08:00
    从安全角度和业务需求上,更倾向于白名单的写法
    huangdayu
        88
    huangdayu  
       2019-01-17 20:31:07 +08:00
    @lincanbin 还有 http://baidu.中国 等
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5400 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 08:21 · PVG 16:21 · LAX 00:21 · JFK 03:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.