原型链污染防御需冻结核心原型并过滤敏感键名:先冻结object、array、string等原型,再递归清洗输入中__proto__、constructor等危险键,优先白名单机制。

JavaScript 中原型链机制本身不提供安全保护,对象属性是否安全取决于开发者如何控制原型访问和属性写入。关键不是“在原型链上做检查”,而是从源头阻断污染路径、限制原型可变性,并在访问时做精准判断。
冻结原生原型防止被篡改
这是最基础也最有效的防御层。必须在任何第三方脚本或用户输入处理前执行,否则已污染的原型无法恢复。
- 逐个冻结核心原型:Object.freeze(Object.prototype)、Object.freeze(Array.prototype)、Object.freeze(String.prototype)、Object.freeze(Number.prototype)、Object.freeze(Boolean.prototype)
- 注意 Math 不是构造函数,但其属性也可冻结;Function.prototype 和 Date.prototype 同样建议冻结
- 冻结后,任何试图向这些原型添加、删除或修改属性的操作都会静默失败(严格模式下抛错)
过滤敏感键名杜绝污染入口
原型链污染通常由递归赋值触发,而攻击者常通过 __proto__、constructor、prototype 或大小写变体注入。所有外部输入都必须清洗。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 解析 JSON 或合并配置前,递归遍历对象,移除或拒绝包含 __proto__、constructor、prototype 的键(包括 __PROTO__、Constructor 等常见变形)
- 优先采用白名单机制:只允许明确声明的字段名被写入,其余一律忽略
- 避免使用存在风险的工具函数,如旧版 lodash.merge(
安全访问自有属性避开原型干扰
即使原型已被污染,只要访问逻辑不依赖原型链查找,就能避免误用恶意属性。
- 用 Object.hasOwn(obj, 'prop') 替代 obj.hasOwnProperty('prop'),前者不可被覆盖,且只查对象自身属性
- 调用方法前用 typeof obj.method === 'function' 校验类型,比 if (obj.method) 更可靠(避免 falsey 值误判)
- 多层访问用可选链 ?.:obj?.data?.items?.length,任意环节为 null/undefined 都不报错
选用安全的数据操作替代方案
深拷贝、合并、赋值等操作是高危区,应替换为更可控的实现。
- 浅拷贝用 Object.assign({}, input),不涉及原型遍历
- 需要深拷贝时,现代环境优先用 structuredClone(input),它天然跳过原型相关键
- Node.js 可启动时加 --disable-proto=throw 参数,让 __proto__ 赋值直接崩溃,强制暴露问题
- 手动实现递归逻辑时,始终跳过 '__proto__'、'constructor'、'prototype' 这三类键名
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










