Object.getPrototypeOf是只读诊断工具,用于精准识别原型链污染节点而非修复;它返回对象真实[[Prototype]]值,可递归遍历校验每层原型是否被非法扩展,并为冻结、重建、拦截等修复动作提供依据。

Object.getPrototypeOf 本身不用于“实现污染”,而是用于检测、遍历和验证原型链——它是一个只读的诊断工具。所谓“深度修复原型链污染”,核心不是用它来操作,而是靠它精准识别被篡改的原型节点,再配合其他安全手段清理或阻断污染路径。
明确 Object.getPrototypeOf 的定位
该方法返回对象真实的 [[Prototype]] 值,不可写、不触发副作用,是判断原型归属的黄金标准:
- 它不会修改任何原型,也不能“修复”污染;它的作用是告诉你“当前对象真正连在哪”
- 例如:
Object.getPrototypeOf({}) === Object.prototype恒为 true,哪怕Object.prototype.isAdmin = true已被注入,这个等式依然成立——污染发生在原型对象上,而非链接关系本身 - 若发现
Object.getPrototypeOf(obj) === Object.prototype但obj.constructor !== Object或obj.toString !== Object.prototype.toString,就提示原型对象可能已被污染
递归遍历原型链以定位污染源头
利用 Object.getPrototypeOf 向上递归,可系统性检查每层原型是否被非法扩展(如意外出现 __proto__、constructor、toString 等敏感键):
- 从目标对象开始,逐级获取原型:
let p = obj; while (p = Object.getPrototypeOf(p)) { /* 检查 p */ } - 对每一层
p,执行安全属性扫描:只允许存在原生自有属性(可用Object.getOwnPropertyNames(p)获取),过滤掉用户注入的非常规键(如isAdmin、toString被重写、__proto__出现在非原始包装对象上) - 重点校验顶层原型:
Object.getPrototypeOf(Object.prototype) === null必须为 true;若为 false,说明Object.prototype的原型被篡改,属严重逃逸
结合污染修复的三类关键动作
仅靠 Object.getPrototypeOf 无法修复,但它是触发修复的前提。真实修复需组合以下操作:
-
冻结污染原型:对已确认被污染的原型(如
Object.prototype),立即调用Object.freeze(Object.prototype)阻止进一步写入(注意:freeze 不可逆,且对已有属性无效,仅防新增) -
重建干净实例:避免复用可能携带污染的对象。用
Object.create(null)创建无原型基础的对象,或用Object.setPrototypeOf({}, cleanProto)显式绑定可信原型 -
拦截危险合并逻辑:在
merge、assign类函数中,对每个 key 做白名单校验——若 key 是"__proto__"、"constructor"、"prototype",直接跳过或报错,不进入递归分支
一个轻量修复辅助函数示例
该函数不直接“修复”,而是返回污染证据,供后续决策:
function inspectPrototypeChain(obj, depth = 0) {
if (depth > 10) return { error: 'Prototype chain too deep' };
const proto = Object.getPrototypeOf(obj);
if (proto === null) return { clean: true };
<p>// 检查当前原型是否含高危属性
const keys = Object.getOwnPropertyNames(proto);
const dangerous = keys.filter(k => ['<strong>proto</strong>', 'constructor', 'prototype'].includes(k) ||
k.startsWith('__') || k === 'toString');</p><p>if (dangerous.length > 0) {
return {
polluted: true,
level: depth,
prototype: proto,
dangerousKeys: dangerous
};
}</p><p>return inspectPrototypeChain(proto, depth + 1);
}调用 inspectPrototypeChain(userInput) 可快速定位哪一层原型开始异常,再针对性 freeze 或隔离。

















