当前位置:首页 > 时尚

存在漏洞的javascript库

```html 存在漏洞的存漏javascript库

存在漏洞的javascript库

去年十月,一个做电商的存漏朋友半夜给我打电话,说网站被拖库了。存漏我问他用了什么框架,存漏他说前端用了一个叫 event-stream 的存漏包来加解密用户信息。我当时就沉默了。存漏这个包在 2018 年就被爆出过恶意代码注入,存漏作者把维护权转给了一个陌生人,存漏那人往里面塞了 flatmap-stream,存漏专门偷比特币钱包。存漏朋友用的存漏版本恰好是 3.3.6,一个被官方标记为“废弃”却依然在 npm 上被下载了上百万次的存漏版本。

很多人以为只有老旧的存漏 jQuery 插件才会出问题。错。存漏越是存漏流行的库,越容易变成靶子。lodash 够主流吧?2019 年爆出原型污染漏洞,影响超过 400 万个项目。攻击者构造一个 JSON,比如 { "constructor": { "prototype": { "isAdmin": true}}},只要你的代码里有一句 _.merge({ }, userInput),整个应用的权限判断就废了。我当时在测试环境复现,只花了三分钟就拿到了管理员面板的访问权。那个项目用的还是 lodash 4.17.11,官方在 4.17.12 才修掉。

更麻烦的是依赖链。你直接用的库可能没问题,但它依赖的库有问题。比如 axios 曾经有个 SSRF 漏洞(CVE-2020-28168),攻击者能通过构造 URL 让服务器去访问内网地址。但 axios 本身没写错,是它底层的 follow-redirects 在重定向时没过滤协议。你装 axios 的时候,npm 会悄悄把 follow-redirects 也拉下来,版本号藏在 package-lock.json 的几百行里。有几个开发者会逐行看那个文件?

我见过最离谱的案例是一个内部管理后台。前端用了 serialize-javascript 来序列化用户配置,版本 2.1.1。这个库在 2020 年被发现存在 XSS 漏洞——只要用户输入里带 </script> 这种闭合标签,序列化后的字符串就能直接注入页面。开发团队当时还在用,因为“没时间升级”。结果一个运营人员在配置里填了段带脚本的 HTML,所有访问那个页面的同事都被重定向到了钓鱼站。事后查日志,漏洞利用代码就藏在序列化后的 JSON 里,长得跟正常数据一模一样。

为什么这些漏洞能活这么久?npm 的生态太松了。一个包可能几年没人维护,但下载量依然很高。left-pad 事件还记得吧?一个只有 11 行代码的包被作者撤下,半个互联网的构建都挂了。漏洞库比这更隐蔽——它不会让构建失败,只会让你的用户数据悄悄流出去。我查过 snyk 的数据库,光是 2023 年新增的 JavaScript 库漏洞就有 1700 多个,其中 40% 的修复版本发布时间距离漏洞公开超过了 30 天。三十天,够攻击者写三波利用脚本了。

那怎么办?别指望 npm audit 能救你。它只会告诉你“有漏洞”,但不会告诉你这个漏洞在你的代码路径里能不能被触发。我现在的习惯是:每次引入新库,先看它的 GitHub issue 里有没有人提安全问题,再看最近一次 commit 是不是在半年内。如果两个答案都是“没有”和“超过一年”,我宁可自己写个简单实现。比如那个 is-odd 库,就为了判断奇偶,结果依赖了 is-number,而 is-number 又依赖了 kind-of——三个包加起来快 200KB,还爆过 ReDoS 漏洞。我自己写一行 n % 2 !== 0 不好吗?

说到底,JavaScript 库的漏洞不是技术问题,是信任问题。你信任一个陌生人的代码跑在你的服务器上,处理你的用户数据。那个陌生人可能早就忘了自己写过这个库,也可能故意留了后门。下次 npm install 的时候,不妨点开 node_modules 里那个文件夹,看看里面的代码。你可能会发现,那个下载量千万次的库,最后一次更新是三年前,而它的 README 里还写着“欢迎提交 PR”。

```

分享到: