多灾多难,今天又来了零宽字符,导致字符串手机号在数据库查询不出结果 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
xiangyuecn
V2EX    程序员

多灾多难,今天又来了零宽字符,导致字符串手机号在数据库查询不出结果

  •  
  •   xiangyuecn
    xiangyuecn 2020-11-14 14:41:13 +08:00 4636 次点击
    这是一个创建于 1791 天前的主题,其中的信息可能已经有所发展或是发生改变。

    昨天帖了一个 字符串首尾空格对数据库查询的影响的帖子 《发现多种数据库 group by 对字符串首尾空格的坑死人不偿命规范》 /t/724866 ,len 、length 、=、!= 、in 数据库查询均受影响,有人怪开发者怎么不去掉结尾空格就存到了数据库 数据是数据,不到一定需要的时候,多写一个 trim 都是在篡改用户提交的合法数据,你不能阻止别人发消息给你后面发空格吧

    今天又突然发现,微信里面复制出一个手机号,居然查询不出数据,但人肉去翻又能找到这个手机号,如:

    "13012345678" length=12,结尾有个 \u202C 

    嗯,多了一个零宽的控制字符,肉眼不可见,非常难排查。

    我是不背锅的,这次这个锅要让苹果来背了,他们出品的手机系统里面复制电话号码似乎就会产生这种问题 \u202D 130123456789 \u202C 。顺利甩锅。

    打个针,估计会有人反驳:自己不做格式过滤怪谁,手机号不都是数字的吗

    感觉纯字符串,要处理掉非法的零宽字符还是异常困难的,至少要维护一个 Unicode 名单,和研读字符的各种控制规则,比如常见的 emoji 拼接字符:\u200D,独立出现就是非法,但在多个 emoji 字节码里面又能准确的表达一个复杂的 emoji 。简单的去掉一些黑名单字符还是可以的,比如胡乱越界显示的泰文

    周末祝大家代码无 bug,早日结尾款(或多发奖金)。

    第 1 条附言    2020-11-14 16:07:58 +08:00

    只针对合法的用户输入中的非法零宽字符,比如一个搜索,可以搜名字或手机号,简单点就直接sql(伪代码):

    name like %?% or tel like ?% 

    参数可以是名字:"李逵"!="李逵" 后面这个其实是"李鬼",结尾藏了一个零宽字符

    参数可以是手机号,如果是手机号就完全是精准前缀匹配,但并不会去做特殊格式校验(虽然可以做),小系统里面这种简单查询没必要这么细致操作,浪费时间又没工钱

    17 条回复    2020-11-15 23:09:41 +08:00
    debuggerx
        1
    debuggerx  
       2020-11-14 14:52:25 +08:00   1
    chinvo
        2
    chinvo  
       2020-11-14 14:52:38 +08:00   2
    但是手机号这种东西本身就不会有空格, 为什么不 trim

    你这话说的就跟 UCG 得留着 XSS 不被利用不处理一样怪
    laminux29
        3
    laminux29  
       2020-11-14 14:55:25 +08:00
    经验问题。

    1.要不要对用户输入的数据,做格式化处理,要看情况。

    2.如果数据库需要保存的是手机号码,那么这种情况是需要对用户输入的数据进行格式化处理的,而且是需要按照手机号码规范进行处理。那些不在规范里的字符,比如零宽字符,在入库前就需要处理掉。
    holulu
        4
    holulu  
       2020-11-14 15:45:24 +08:00
    要假设所有外部输入都可能出问题才对吧。
    heyjei
        5
    heyjei  
       2020-11-14 15:56:44 +08:00
    不只是苹果手机,我在 windows 10 里复制文字也 经常出现这种不可见的,但又不是零宽的字符
    yyid
        6
    yyid  
       2020-11-14 16:02:31 +08:00
    linux 文本在 windows 编辑器打开。\n 被改成 \r\n 了。。。一堆坑
    zjsxwc
        7
    zjsxwc  
       2020-11-14 16:12:08 +08:00
    @chinvo 貌似普通 trim 默认只能 把空格 tab 换行删掉,这个还干不掉。
    xiangyuecn
        8
    xiangyuecn  
    OP
       2020-11-14 16:15:01 +08:00
    @debuggerx #1 看了一下,发现他对 emoji \u200D 连接过的 处理也是一个难题,还是 todo 中
    lucybenz
        9
    lucybenz  
       2020-11-14 16:15:18 +08:00
    为赋新词强说愁
    xiangyuecn
        10
    xiangyuecn  
    OP
       2020-11-14 16:28:14 +08:00
    @lucybenz #9 哈,被你发现了,10 年专业造词,别人绝对看不懂
    xuanbg
        11
    xuanbg  
       2020-11-14 17:24:03 +08:00
    不合法的空格当然要处理掉啊。用户输入是不可信的,必须要进行合法性验证。没弹框警告非法字符,悄悄处理掉多余空格已经算是照顾用户体验了好吧。
    dblpx
        12
    dblpx  
       2020-11-14 18:29:44 +08:00 via iPhone
    涨知识了,谢谢楼主
    abc612008
        13
    abc612008  
       2020-11-14 18:48:15 +08:00
    tel like ?%那输入个 1 不就能爆出所有手机号了
    xiangyuecn
        14
    xiangyuecn  
    OP
       2020-11-14 19:00:06 +08:00
    @xuanbg #11 @abc612008 #13 唯有苦笑而不语
    JerryCha
        15
    JerryCha  
       2020-11-15 11:53:26 +08:00
    已知中国内地的手机号都是 11 位
    于是不以+86 开头的输入直接判断是不是 11 位,不是就给老子爬
    azh7138m
        16
    azh7138m  
       2020-11-15 18:15:26 +08:00
    微信老问题了
    手机号入库得做 trim 的
    longaiwp
        17
    longaiwp  
       2020-11-15 23:09:41 +08:00
    这是一个常见问题,在很多系统里都会出现,当然可能应用内也有自己的处理,就是怎么去处理 BiDi,也就是去处理字的方向。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2687 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 15:06 PVG 23:06 LAX 08:06 JFK 11:06
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86