防范原型污染需从运行环境、对象创建、数据处理三层面协同设防:冻结六类原型、用object.create(null)或map替代{}、禁用for...in、严格过滤输入、升级合并工具、启用structuredclone等安全方案。

防止原型污染攻击,核心是切断攻击者向 Object.prototype 等共享原型写入属性的路径。这不是靠单点修补能解决的问题,而需要从运行环境、对象创建、数据处理三个层面协同设防。
尽早冻结关键原型对象
这是最硬核的底层防护。用 Object.freeze() 锁死原生构造函数的原型,可让其进入不可变更状态:无法新增、删除、修改任何自有属性,也无法改变属性描述符。
- 必须在页面第一个
<script></script>的最顶部执行,早于所有第三方脚本(含埋点 SDK、统计代码、polyfill) - 需同步冻结六类原型:
Object.prototype、Array.prototype、Function.prototype、String.prototype、Boolean.prototype、Date.prototype - 严格模式下尝试污染会立即报错;非严格模式下静默失败,同样可阻断攻击链
业务层避免使用普通对象做配置或映射
{} 默认继承 Object.prototype,天然暴露在污染风险中。一旦原型被注入 admin 或 toString,所有空对象都会“自动获得”这些属性。
- 配置对象、路由表、字段映射表等场景,统一改用
Object.create(null)创建无原型对象 - 需要键值对存储且要求高安全性时,优先选用
Map:它不继承任何原型,键支持任意类型,完全规避原型链查找 - 遍历对象时不用
for...in,改用Object.keys(obj)或Object.getOwnPropertyNames(obj),避免意外访问原型属性
严格过滤用户输入与合并操作
冻结原型是兜底手段,但污染往往发生在数据落地环节。所有来自外部(JSON、URL、表单、API)的数据,在写入目标对象前必须清洗。
- 禁止直接
Object.assign(target, input)或递归赋值不可信输入 - 递归遍历并删除
__proto__、constructor、prototype及其大小写变体(如__PROTO__、Constructor) - 更可靠的做法是白名单机制——只保留明确允许的字段名,其余一概丢弃
升级依赖并启用安全替代方案
很多原型链污染漏洞源于第三方库的深拷贝/合并逻辑缺陷,例如旧版 lodash 、<code>hoek 。
- 检查项目依赖,将
lodash升级至4.17.21+,启用customizer或改用assignInWith控制合并行为 - 现代环境中优先使用
structuredClone()替代不安全的深拷贝函数 - Node.js 服务可启用
--disable-proto=throw运行参数,强制拦截非法原型访问
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











