Prototype Pollution Prevention Cheat Sheet / 原型污染防护清单¶
Explanation / 说明¶
Prototype Pollution is a critical vulnerability that can allow attackers to manipulate an application's JavaScript objects and properties, leading to serious security issues such as unauthorized access to data, privilege escalation, and even remote code execution.
原型污染是一种关键漏洞,允许攻击者操纵应用程序的 JavaScript 对象和属性,导致严重的安全问题,如未经授权的数据访问、权限提升,甚至远程代码执行。
For examples of why this is dangerous, see the links in the Other resources section below.
有关为什么这很危险的原因示例,请参阅下面其他资源部分的链接。
Suggested protection mechanisms / 建议的保护机制¶
Use "new Set()" or "new Map()" / 使用 "new Set()" 或 "new Map()"¶
Developers should use new Set() or new Map() instead of using object literals:
开发者应使用 new Set() 或 new Map() 而不是使用对象字面量:
let allowedTags = new Set();
allowedTags.add('b');
if(allowedTags.has('b')){
//...
}
let options = new Map();
options.set('spaces', 1);
let spaces = options.get('spaces')
If objects or object literals are required / 如果需要对象或对象字面量¶
If objects have to be used then they should be created using the Object.create(null) API to ensure they don't inherit from the Object prototype:
如果必须使用对象,则应使用 Object.create(null) API 创建对象,以确保它们不会从 Object 原型继承:
let obj = Object.create(null);
If object literals are required then as a last resort you could use the __proto__ property:
如果需要对象字面量,则作为最后的手段,可以使用 __proto__ 属性:
let obj = {__proto__:null};
Use object "freeze" and "seal" mechanisms / 使用对象的 "冻结" 和 "密封" 机制¶
Freezing built-in prototypes with Object.freeze() prevents adding or removing their properties and makes existing data properties non-writable. Freezing is shallow: objects referenced by those properties remain mutable unless separately frozen. Test compatibility first, because libraries that modify built-in prototypes can break.
使用 Object.freeze() (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) 冻结内置原型,防止添加或删除其属性,并使现有数据属性不可写。冻结是浅层的:那些属性引用的对象仍然可变,除非单独冻结。首先测试兼容性,因为修改内置原型的库可能会破坏程序。
Object.seal() only prevents adding or removing properties and changing their configuration; existing writable property values can still change. Do not rely on sealing to prevent those modifications.
Node.js configuration flag / Node.js 配置标志¶
Node.js also offers the ability to remove the __proto__ property completely using the --disable-proto=delete flag. Note this is a defense in depth measure.
Node.js 还提供使用 --disable-proto=delete 标志完全删除 __proto__ 属性的能力。注意,这是一个深度防御措施。
Prototype pollution is still possible using constructor.prototype properties but removing __proto__ helps reduce attack surface and prevent certain attacks.
仍然可以使用 constructor.prototype 属性进行原型污染,但删除 __proto__ 有助于减少攻击面并防止某些攻击。
Other resources / 其他资源¶
- What is prototype pollution? (Portswigger Web Security Academy)) (什么是原型污染?(Portswigger 网络安全学院))
- Prototype pollution (Snyk Learn)) (原型污染(Snyk 学习))
Credits / 致谢¶
Credit to Gareth Hayes for providing the original protection guidance in this comment.
感谢 Gareth Hayes 提供了原始的保护指南 在此评论中。
References / 参考¶
- MDN: JavaScript prototype pollution) (MDN:JavaScript 原型污染)
- Node.js: Command-line API) (Node.js:命令行 API)