检测javascript原型链污染需检查object.prototype等内置原型上是否存在非标准、意外新增的可枚举属性;通过对比标准属性列表与object.getownpropertynames获取的自有属性,并用propertyisenumerable判断可枚举性来识别污染。

检测 JavaScript 中对象的原型链是否被污染,核心是检查 Object.prototype(或 Function.prototype、Array.prototype 等内置原型)上是否存在**非标准、意外新增的可枚举属性**。污染通常表现为在这些原型上直接添加了属性或方法(如 Object.prototype.polluted = true),导致所有对象都继承该属性,可能引发安全问题或逻辑错误。
检查 Object.prototype 是否被污染
这是最常见也最危险的污染场景。可通过遍历 Object.prototype 的自有属性,并排除标准属性来识别异常:
- 使用
Object.getOwnPropertyNames(Object.prototype)获取所有自有属性名(包括不可枚举的) - 对比已知的标准属性列表(如
toString、valueOf、hasOwnProperty等) - 对每个属性,用
Object.prototype.propertyIsEnumerable(prop)判断是否为可枚举属性(污染常通过Object.prototype.xxx = ...添加,这类赋值默认可枚举)
简易检测函数示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function isObjectPrototypePolluted() {
const standardKeys = new Set([
'toString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf',
'propertyIsEnumerable', 'toLocaleString', '__defineGetter__',
'__defineSetter__', '__lookupGetter__', '__lookupSetter__'
]);
const props = Object.getOwnPropertyNames(Object.prototype);
for (const prop of props) {
if (!standardKeys.has(prop) && Object.prototype.propertyIsEnumerable(prop)) {
return true; // 发现可疑的可枚举属性
}
}
return false;
}
检查其他内置原型(如 Array.prototype、Function.prototype)
攻击者也可能污染其他原型。检测方式类似,只需替换目标原型对象:
-
Object.getOwnPropertyNames(Array.prototype)检查数组方法是否被篡改或注入 -
Object.getOwnPropertyNames(Function.prototype)检查函数相关行为是否异常 - 注意:某些合法库(如旧版 Prototype.js)会扩展原型,需结合项目上下文判断是否属于“污染”
运行时动态检测——拦截新建对象的异常继承
更主动的方式是在关键路径中验证对象是否“意外继承”了不该有的属性:
- 创建一个干净对象:
const clean = Object.create(null)(不继承任何原型) - 对比普通对象(如
{})与clean的Object.keys()或for...in结果差异 - 若
{}多出非标准属性(如polluted、exec、eval),说明原型链已被污染
预防优于检测
检测是兜底手段,生产环境应优先避免污染发生:
- 禁用全局原型修改:通过 ESLint 规则
no-extend-native提前拦截 - 使用
Object.create(null)创建无原型对象,尤其处理不受信数据时 - 服务端 Node.js 可在启动时冻结关键原型:
Object.freeze(Object.prototype)(注意兼容性影响) - 避免使用
with、eval和不安全的JSON.parse回调(如配合__proto__注入)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










