如果你和我们一样,npm install xxx 用的很舒服,可能你的项目会遇到重大的危险。
先来看看一篇别人家的文章——细思极恐:后门代码被隐藏在 npm 模块中,差点就得逞
为了节省时间,点击问题讨论地址,直接看看别人怎么说的
可能你看了那篇文章也不太清除发生了什么,那就请看下面
问题描述
哪些人会出现这样的问题?
直接 or 间接使用 getcookies 的人。
比如:你正在使用的 Node 框架是 express,并且通过 express-cookies 处理 cookie 功能。那它其中就引用了 getcookies。
问题有多严重?
getcookies 会通过 header 注入代码,然后在你服务器‘任意遨游’,获取你服务器配置信息、监控你请求、让你宕个机…
它是怎么个原理
- inject 自定义的 Header,获取到 req.headers
1 | req.headers['gfeffh11i'] = 111; |
- 在请求头中寻找符合/g([a-f0-9]{4})h((?:[a-f0-9]{2})+)i/gi规则的信息
1 | ... |
判断注入非法的信息,完成:初始化代码执行环境–>将问题代码添加至内存中–>调用 vm 执行问题代码
注释信息,说明了哪些 header 会被 switch 命中script 脚本如何在 vm 执行(写了个 Demo 模拟)
1 | // 模拟header中数据的获取,存入内存的过程(default中的逻辑) |
你可能需要准备下其他知识
readUInt16LE 什么意思
如果你不清楚 LE、BE。可以再看看这篇:readInt16BE 和 readInt16LE 的区别\x76\x6d 是什么格式?
是 16 进制。
然后就能明白源代码中:
1 | require('\x76\x6d')['\x72\x75\x6e\x49\x6e\x54\x68\x69\x73\x43\x6f\x6e\x74\x65\x78\x74'] |
对应的再补充一些进制转换api
1
2
3
4
5
6
7
var test10 = 43981;
// 10 --> 2
var test2 = test10.toString(2);//1010101111001101
// 2 --> 10
var backTest10 = parseInt(test2, 2);//43981
// 10 -> 16
var testHex = parseInt(test2, 2).toString(16);//abcd
- 什么是 vm?
执行 script,同时源码中还用了高阶 Fn,提供了 module.exports, require, req, res, next 等信息。我这些都拿到了,我还有什么不能做?
现状
npm 官方已经做了处理,你已经下不到这两个包了
1 | Error: [getcookies@*] GET https://registry.npm.taobao.org/getcookies/latest response 404 status |
总结
- 不要着急升级模块,避免已稳定的模块出现问题
- 下载使用优质,热门模块。用的人多,这样出问题,社区会有解决方案,你不是一个人战斗。
- 检查下项目中的 node_modules,奇奇怪怪的能不用就别用了。
- 提升自己能力,看的懂大神们写的代码才能 hold 全场,慢慢积累,但别放弃任何学习源码的机会,比如这个 getcookie 现在就下载不到了。
附录
getcookie 源码
1 | /* eslint-env es6 */ |