排查原型链污染需先检查object.prototype是否被非法写入并生效,再定位源头:执行过滤非常规键的代码确认污染痕迹,通过新建对象访问疑似属性验证是否真实生效,重点审查json解析、参数解析、旧版工具库及手动深拷贝等污染高发环节。

排查原型链污染带来的安全漏洞,核心是确认 Object.prototype 是否被非法写入,以及该写入是否实际影响了运行时对象行为。不能只看“有没有属性”,而要看“有没有生效”“谁写的”“在哪用的”。
快速检查 Object.prototype 是否已被污染
在浏览器控制台或 Node.js 调试环境中直接执行:
Object.getOwnPropertyNames(Object.prototype).filter(key => !({toString:1, valueOf:1, constructor:1, hasOwnProperty:1, isPrototypeOf:1, propertyIsEnumerable:1})[key])
若返回非空数组(如出现 isAdmin、__exp、polluted 等非常规键),说明已存在污染痕迹。建议在干净环境(如新标签页空白页)中先运行一次作为基线,再比对差异。
验证污染是否真实生效
仅发现异常键还不够,必须确认它能被普通对象读取并覆盖默认行为:
- 新建一个空对象:
const test = {} - 访问疑似污染属性:
test.isAdmin或test.toString() - 若返回非
undefined或非原生值(例如test.toString === 'hacked'),且该属性未在test自身定义(test.hasOwnProperty('isAdmin') === false),即证实污染已生效 - 进一步测试不同来源对象:
JSON.parse('{}').isAdmin、new Date().isAdmin、Array.from([]).isAdmin,观察是否全部返回相同值,判断污染范围
定位污染源头的关键位置
污染通常发生在数据落地环节,重点排查以下几类代码:
- 后端返回的 JSON 字符串含
{"__proto__": {"x": 1}},被JSON.parse()后直接传给lodash.merge、_.set等函数 - URL 查询参数或表单字段经
qs.parse、URLSearchParams解析成对象,再递归赋值到全局配置对象,未过滤敏感键名 - 使用旧版工具库:如
lodash 的 <code>merge默认允许遍历__proto__;hoek 的 <code>deepMerge存在类似问题 - 手动实现的深拷贝或递归赋值函数,未对
__proto__、constructor、prototype及其大小写变体(如__PROTO__)做拦截或跳过
运行时监控与拦截写入行为
在开发或测试环境注入轻量级防护逻辑,主动捕获非法修改:
- 用
Object.defineProperty临时重写Object.prototype.__proto__的 setter,抛出带调用栈的错误 - 对已知高危函数(如
lodash.merge、_.set、自定义deepAssign)打补丁,在入口处加日志,检查输入source是否含敏感键 - 在关键合并操作前后插入断点,观察
target和source的键名列表,重点关注是否出现原型相关字段
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











