对象属性污染指不该出现的属性被意外写入对象(尤其是原型链),排查重点是识别多出、异常或影响全局的属性,需检查自有属性、原型链、写入源头并实施运行时防护。

对象属性“污染”通常指不该出现的属性被意外写入对象(尤其是原型链),导致行为异常或安全风险。排查重点不是找“错”,而是找“多出来的”“不该有的”或“影响全局的”属性。
检查对象自身是否混入了敏感键
先确认污染是否发生在当前对象本身,而非原型上:
- 用 Object.keys(obj) 查看所有可枚举自有属性,快速识别如
__proto__、constructor、prototype等异常键名 - 用 Object.getOwnPropertyNames(obj) 补充获取不可枚举属性(比如某些库会把污染键设为不可枚举)
- 对比预期字段白名单:如果该对象应只含
id、name、email,却出现admin或toString,就要警惕
追溯原型链上是否被注入属性
污染常藏在 Object.prototype 或中间原型上,影响所有对象:
- 执行 console.log(Object.prototype),直接查看其属性列表,留意是否有业务无关的字段(如
isAuth、exec、run) - 逐级向上检查:
obj.__proto__→obj.__proto__.__proto__→ 直到null,观察哪一层多出了可疑属性 - 用 Object.getOwnPropertyNames(Object.prototype) 获取完整键名列表,搜索大小写变体(如
__PROTO__、Constructor)
监控属性写入源头
污染往往来自用户输入的解析或合并操作,需定位触发点:
- 搜索代码中是否存在
JSON.parse()后直接Object.assign()或lodash.merge()的调用,尤其参数含外部数据(URL查询、表单、API响应) - 检查深拷贝/合并函数是否传入了未过滤的源对象;旧版 lodash merge 默认允许
__proto__写入 - 在关键赋值语句前加断点,观察
key变量值——若 key 是"__proto__"或"constructor",基本可确认污染路径
运行时防护与快速验证
部署阶段可加入轻量检测机制,辅助日常排查:
- 启动时执行 Object.freeze(Object.prototype),后续任何尝试修改都会抛出错误(注意兼容性,IE 不支持)
- 写一个简单校验函数,在关键对象生成后调用:
function checkForPollution(obj) {
if (obj && typeof obj === 'object') {
const keys = Object.keys(obj);
if (keys.some(k => /^__proto__$|^(constructor|prototype)$/i.test(k))) {
console.warn('Suspicious key found:', keys.filter(k => /^__proto__$|^(constructor|prototype)$/i.test(k)));
}
}
} - 使用 Chrome DevTools 的 Console > “Enable custom formatters”,配合自定义 formatter 显示对象原型链结构,便于肉眼识别异常层级
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











