object.getprototypeof 是识别原型污染的关键探针,可检测实例原型是否被篡改、建立快照链定位篡改环节、配合冻结与校验实现防御,并协同 proxy 追踪篡改行为。

Object.getPrototypeOf 本身不能直接还原“非法修改原型”的背景,但它能帮你检测和定位原型被篡改的事实,是全链路追踪中识别原型污染的关键探针。
识别原型是否被意外或恶意替换
在关键构造函数(如 Request、Response、Date、Array)实例化后,立即用 Object.getPrototypeOf 检查其原型是否仍指向预期的内置原型对象。一旦发现不一致,说明该实例的原型链已被干预。
- 例如:
const req = new Request('/'); if (Object.getPrototypeOf(req) !== Request.prototype) { /* 原型被替换 */ } - 注意:不能只比对 constructor,因为 constructor 属性可被轻易伪造;而 Object.getPrototypeOf 返回的是真实内部 [[Prototype]],更可靠
在中间件或拦截点建立原型快照链
在请求进入框架核心逻辑前(如 Express 的 pre-route 阶段、Fetch 拦截器、或自定义代理 handler),为关键对象记录其原型引用快照,并绑定到当前 traceId 下。
- 可将
Object.getPrototypeOf(obj)结果存入全局追踪上下文(如 AsyncLocalStorage),标注时间戳与调用栈 - 后续任一环节发现原型异常时,对比快照即可确认篡改发生在哪两个快照之间
- 配合 stacktrace-js 或
new Error().stack,能准确定位篡改代码位置
防御性封装:冻结原型链 + 运行时校验
仅靠追溯不够,需主动防御。对敏感类实例,在创建后立即冻结其原型链,并在关键方法调用前做轻量校验。
- 使用
Object.freeze(Object.getPrototypeOf(obj))(注意:仅冻结目标对象,不递归) - 在高危方法(如
req.json()、res.send())入口处插入校验:if (Object.getPrototypeOf(req) !== Request.prototype) throw new Error('Prototype tampered at traceId: ' + currentTraceId) - 校验失败时,自动上报 traceId、原型值、Error.stack 和当前执行模块路径,供链路分析平台聚合归因
与 Proxy 协同实现细粒度原型行为追踪
若需监控“谁在何时替换了原型”,可在构造函数返回前,用 Proxy 包裹实例,劫持 __proto__ 设置和 Object.setPrototypeOf 调用。
- Proxy handler 中的
set对于obj.__proto__ = x,或apply对于Object.setPrototypeOf(obj, x),均可捕获并记录调用方信息 - 结合
Object.getPrototypeOf当前值与新值,判断是否属于合法升级(如继承扩展)还是越权覆盖 - 此类 Proxy 应仅在开发/灰度环境启用,避免线上性能损耗
不复杂但容易忽略:原型污染往往不抛错,却让后续逻辑静默失效。Object.getPrototypeOf 是你拿到的第一手“链路指纹”,用好它,就能把模糊的“哪里坏了”变成清晰的“谁在哪个环节动了原型”。










