防范原型污染需从运行环境、对象创建、数据处理和编码习惯四层面协同设防:冻结六类原型、用Object.create(null)或Map替代{}、禁用for...in、严格过滤输入、升级合并工具、启用严格模式及原型方法校验。

防范原型污染的核心是切断攻击者向 Object.prototype 等共享原型写入属性的路径。这不是靠某一个技巧就能解决的问题,而是需要从运行环境、对象创建、数据处理和编码习惯四个层面协同设防。
尽早冻结关键原型对象
这是最硬核、最底层的防御手段。一旦冻结,任何尝试修改原型的操作(包括添加、删除、重写属性)都会在严格模式下立即报错,在非严格模式下静默失败。
- 必须在页面第一个 <script> 的第一行执行,早于所有第三方脚本(含埋点、统计、polyfill)
- 需冻结的六类原型:Object.prototype、Array.prototype、Function.prototype、String.prototype、Boolean.prototype、Date.prototype
- 示例:Object.freeze(Object.prototype); Object.freeze(Array.prototype); 等六行必须前置
业务层避免使用普通对象做安全敏感结构
{} 默认继承 Object.prototype,天然带污染风险。只要攻击者控制了键名(比如 "__proto__"),就可能绕过表面逻辑直接污染全局原型。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 配置表、路由映射、字段白名单等场景,统一改用 Object.create(null) 创建无原型对象
- 需要键值对存储且要求高安全性时,优先选用 Map:它不继承任何原型,键支持任意类型,完全规避原型链查找
- 遍历对象时不用 for...in,改用 Object.keys(obj) 或 Object.getOwnPropertyNames(obj),避免意外访问到原型属性
严格过滤用户输入与合并操作
冻结原型是兜底,但污染往往发生在数据落地环节。所有来自外部(JSON、URL、表单、API)的数据,在写入目标对象前必须清洗。
立即学习“Java免费学习笔记(深入)”;
- 明确禁止以下键名及其大小写变体:__proto__、constructor、prototype
- 推荐白名单策略:只允许明确声明的字段名,其余一律丢弃,不依赖黑名单“堵漏”
- 慎用老旧深拷贝/合并工具(如 lodash <4.17.12 的 _.merge),升级到修复版本,或改用原生 structuredClone()(现代环境支持)
启用监控与防御性编码习惯
主动识别异常比被动拦截更可靠。
- 开发和测试环境强制开启 "use strict",让原型污染操作(如给 __proto__ 赋值)直接抛出 TypeError,便于快速定位问题代码
- 对关键原型方法做运行时校验,例如检查 obj.hasOwnProperty === Object.prototype.hasOwnProperty,防止被覆盖
- 避免在业务逻辑中直接调用 obj.__proto__ 或 obj.constructor.prototype,减少隐式原型操作

















