原型属性污染会扩散至所有后续对象,需立即切断源头并清理;检测用({}).pollutedProp和typeof{}.toString;清洗输入需递归扫描并移除整层污染字段;创建对象改用Object.create(null);运行时冻结Object.prototype并禁用__proto__。

原型属性污染不是局部问题,它会像病毒一样扩散到所有后续创建的对象中,导致看似无关的模块突然出现异常行为。关键不是修复某个报错,而是立刻切断污染源头并清理已注入的恶意属性。
立即识别污染是否已发生
在控制台快速执行以下检测语句,确认污染是否生效:
- ({}).pollutedProp === "test" —— 若返回 true,说明 Object.prototype 已被写入
- typeof {}.toString === "function" —— 若返回 "undefined" 或 "string",说明内置方法可能已被覆盖
- 检查常见攻击键名:Object.prototype.__proto__、Object.prototype.constructor 是否存在非原始值
从入口处拦截并清洗输入数据
所有外部数据进入业务逻辑前必须清洗,不能依赖“后面再过滤”:
- 对 JSON.parse() 结果立即递归扫描:遍历每个对象的 所有键名和嵌套路径字符串,匹配正则
/\b(__proto__|constructor|prototype)\b/i - 移除整层污染字段,不只删键,还要跳过其子树(例如
{"a": {"__proto__": {"x": 1}}}中的a整个分支) - URL 参数、表单字段、配置文件加载结果同样适用该清洗逻辑,统一封装为
sanitizeInput(obj)工具函数
替换易受污染的对象创建方式
把所有用于存储用户数据、配置映射、临时缓存等场景的 {} 替换为无原型对象:
立即学习“Java免费学习笔记(深入)”;
- 改用 Object.create(null) 创建干净容器,它没有
__proto__、不继承toString或hasOwnProperty - 需要调用原生方法时,显式借用:
Object.prototype.hasOwnProperty.call(obj, key) - 尤其适用于路由参数解析、插件注册表、请求体中间件缓存等高频、低信任度场景
加固运行时环境防止二次污染
静态防护可能被绕过,需增加运行时兜底措施:
- 服务启动时执行 Object.freeze(Object.prototype),阻止新增/修改属性(注意兼容性,提前验证依赖库)
- Node.js 启动参数加入
--disable-proto=throw,让任何尝试访问__proto__的代码立即抛出错误 - 在预发环境主动注入测试 payload(如
{"__proto__": {"_polluted": 1}}),自动化验证清洗与冻结是否真正生效


















