翻译自:https://dev.to/jankapunkt/all-your-javascript-code-is-polluted-3e8l
好吧,可能不是所有的 Javascript 代码都会(作者有标题党的嫌疑 😂),这是一篇关于 Javascript 的prototype
被污染的短文,我已经不只一次看到这个问题了。
这是怎么回事呢?
如果你使用了 Javscript 的「Object-bracket notation」来创建对象,并且接受用户输入来修改这个对象,那么你的代码很可能已经引入了 Prototype 污染,先来看看一个简单的例子:
1 | const internal = { |
接着这样调用:
1 | // no problem so far, this is the expected input |
经过恶意输入后的结果是,你之后创建的所有对象,都会包含polluted
这个属性,而且它的值是Bon jour 🐻❄️
:
1 | const obj = {}; |
为什么这样会有问题?
在客户端中使用这样 Javascript 问题不大,但是如果这些代码是在服务端(Node.js)的话,这相对于给攻击者开了一个门。如果说攻击者知道你在鉴定用户权限时,使用的是运行时创建的对象而不是Object.create(null)
,那么 Prototype 污染这个问题使他们可以绕过鉴权程序,去获取更多的系统访问权限。
1 | const internal = { |
这只是一个简化之后的例子,希望你能够看到它给系统带来的严重问题。
如何避免这个问题?
- 减少「Object-bracket notation」的使用,尽可能去使用「dot notation」。
- 根据具体场景,适当地使用 Map 或 Set。
- 在深度合并对象时,要注意在 Prototype 链是否受到影响。
- 永远不要相信用户的输入,记得校验,特别的在服务端。
- 使用
Object.create(null)
来创建一个没有 prototype 的对象。
[本文谢绝转载,谢谢]