V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LXGShadow
V2EX  ›  分享发现

简单分析 b 站站内链接的正则匹配以及吐槽

  •  
  •   LXGShadow · 2020-08-05 18:55:09 +08:00 · 2266 次点击
    这是一个创建于 1331 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 V2EX 里发我就尽量简洁一些。

    原文地址: https://www.lxgshadow.us/blog/article-detail/46

    在学正则,想找点例子来看看,看了看 b 站的一部分正则匹配,我真的人傻了。

    刚刚开始学习正则,有错误请指出。


    Part1-专栏投稿中站内链接的正则匹配

    总之都知道 b 站专栏里有添加站内链接的操作,然后检测是否是站内链接是直接写 js 里的。

    站内链接-正则匹配-0.js

    翻出来就是这样

    1.^( http:)?( https:)?(\/\/)?((([a-zA-Z0-9_-])+(\.)?){1,2}\.)?(bilibili.com)+(:\d+)?(\/((\.)?(\?)?=?&?%?[#!a-zA-Z0-9_-](\?)?)*)*$
    
    2.^( http:)?( https:)?(\/\/)?(([a-zA-Z0-9_-])+(\.)?){0,2}(\.biligame.com)+(:\d+)?(\/((\.)?(\?)?=?&?%?[#!a-zA-Z0-9_-](\?)?)*)*$/i
    
    3.^( http:)?( https:)?(\/\/)?(acg.tv)+(:\d+)?(\/((\.)?(\?)?=?&?%?[#!a-zA-Z0-9_-](\?)?)*)*$
    
    4.^(bilibili:\/\/)(\S)+$
    

    先吐槽一下匹配协议的正则^( http:)?( https:)?(\/\/)?,我寻思着他的目的应该是匹配 http://,https://,// 的其中之一。但是用?我是没想到的,这样子连 "http:https://" 都能匹配到。

    acg.tv bypass 1

    写个类似这样的: (( http(s)?:\/\/)|(\/\/))? 就可以解决问题了

    再来说说匹配主域名的(bilibili.com)+,(.biligame.com)+。匹配域名匹配一遍就够了啊,用+干啥,难道你站域名还存在 bilibili.combilibili.com ? (虽然在 1,2 里前面有做最多匹配 3 级域名,这个+似乎也不会起到啥作用)

    (([a-zA-Z0-9_-])+(\.)?){0,2} 这段大概是匹配 1-3 级域名,我觉得还行.....个头。

    ([a-zA-Z0-9_-])+ 没多大问题, 但是 (\.) 加 ? 干嘛,匹配子域名.是必须的啊。哦,原来是为了后面 \.biligame.com

    但是这问题也很大啊,既然都给了?了,那我也可以加 . 啊。如果按这个正则的话 a.a..biligame.com 不是照样能匹配到。

    biligame bypass 1

    \.biligame.com 带来的另一个问题就是这段子表达式根本匹配不到 biligame.com, 必须前面加个 . 才行 (.biligame.com)

    我人傻了

    第一条 bilibili.com 的也是大同小异, 我就不分析了。

    同样给一个可能可以作为替代的 ([a-zA-Z0-9_-]+\.){0,2}(biligame.com)


    Part2-评论区中站内链接的正则匹配

    这段由@Rorical 的文章《优雅的在哔哩哔哩评论区发送链接》 所启发

    判断是否为官方链接的代码依旧写死在 commet.js 里。

    regex in commet

    ( http(s)?:\/\/)?([a-z0-9A-Z]+.)?(bilibili.(com|tv|cn)|biligame.(com|cn)|(bilibiliyoo|im9).com|biliapi.net|b23.tv|sugs.suning.com|kaola.com)(\$|\/|)([\/.$*?~=#!%@&-A-Za-z0-9_]*)(?![^<>]*>|[^"]*?<\/a)

    先说个非常离谱的 (\$|\/|) 我先大胆分析了一下,这段子表达式的功能有两个,第一个: 如果该 url 没有后面的 path,那么用 $ 直接就结束了。如果有后面的 path,那么必须先匹配到一个 / 才行。

    但是我看到这段的时候人都傻了,\$ 好好的 $ 你给他转义干啥啊。 哪个正常人写 url 里带$的。

    还有 (\$|\/|) 子表达式里为什么有三个 | 。匹配空气嘛? 结合后面的正则,难道是想匹配 bilibili.comoihfgiu2b34rkeajsiflbnaiokgba?

    然后就是最最最最最最最最最最离谱的了,所有的 . 都没有转义。

    先是匹配子域名子表达式里的 . 没有转义 ([a-z0-9A-Z]+.)?。那么该表达式几乎等同于 ([a-z0-9A-Z]{1,})? 了?匹配无中生有的子域名?

    commet bypass 2

    然后是域名里的 . 也都没转义。

    commet bypass 3

    结合以上的漏洞,构建一个能够被匹配的二级域名都是轻轻松松的。

    commet bypass 4 aabilibili0com.a.a/fadfasd?a=afda

    当然,评论区这段我不希望 b 站修复。留着还挺有用的。

    当然,评论区这段我不希望 b 站修复。留着还挺有用的。

    当然,评论区这段我不希望 b 站修复。留着还挺有用的。


    后端正则匹配猜测

    前景提要: https://www.v2ex.com/t/684939

    在测试中发现

    尝试 https://www.bilibili.com -> 成功

    尝试 https://www.biligame.com -> 成功

    尝试 https://www.im9.com -> 成功

    尝试 https://www.biliapi.net -> 成功

    尝试 https://www.bilibili.co -> 成功

    尝试 https://aabilibili0com -> 成功, 说明没有转义.

    可以首先构建出一段子表达式(bilibili.com|biligame.com|im9.com|biliapi.net|bilibili.co)

    尝试 https://www.bilibili.com -> 成功

    尝试 https://a.a.a.a.a.bilibili.com -> 成功

    尝试 www.bilibili.com -> 失败

    尝试 https://bilibili.com -> 失败

    尝试 http:https://www.bilibili.com -> 失败

    由此可以推断出,后端的正则匹配必须有 http 或者 https 以及一个二级域名

    结合上一段,构建出子表达式

    ^( http(s)?:\/\/)([a-z0-9A-Z]+.)+(bilibili.com|biligame.com|im9.com|biliapi.net|bilibili.co)

    接下来尝试 2 级域名

    尝试 https://aabilibili0com.a.a -> 失败

    尝试 https://aabilibili0com/.a.a -> 成功

    尝试 https://aabilibili0com -> 成功

    尝试 https://aabilibili0com/ -> 成功

    由此构建子表达式

    ($|\/)([\/.$*?~=#!%@&-A-Za-z0-9_]*)(?![^<>]*>|[^"]*?<\/a)

    结合起来 推测后端正则表达式为

    ^( http(s)?:\/\/)([a-z0-9A-Z]+.)+(bilibili.com|biligame.com|im9.com|biliapi.net|bilibili.co)($|\/)([\/.$*?~=#!%@&-A-Za-z0-9_]*)(?![^<>]*>|[^"]*?<\/a)

    结果 . 依旧没有转义。

    虽然不排除后端根本用的不是正则。

    当然,这段我依旧不希望 b 站修复。留着还挺有用的。

    当然,这段我依旧不希望 b 站修复。留着还挺有用的。

    当然,这段我依旧不希望 b 站修复。留着还挺有用的。


    综上所述,我有理由怀疑,写这些正则的人可能是闭着眼睛写的。

    虽然这些基本无伤大雅,也不会对用户体验造成任何影响 (删掉)甚至增加了我的使用体验(删掉),有些在后端会也会被过滤掉。

    但是麻烦走点心好嘛?

    2 条回复    2020-08-06 18:41:36 +08:00
    lxk11153
        1
    lxk11153  
       2020-08-05 19:06:13 +08:00
    强👍。不去上海工作可惜了
    huermos
        2
    huermos  
       2020-08-06 18:41:36 +08:00
    说不定就是闭着眼写的,反正功能实现了就可以,也没有严重 bug
    程序员工作很多,很累哒
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1540 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:15 · PVG 01:15 · LAX 10:15 · JFK 13:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.