原型链污染是javascript运行机制被恶意利用的结果,因属性访问沿原型链查找且不受控赋值__proto__等键,导致object.prototype被篡改,所有对象继承恶意属性;防御需冻结原型、过滤敏感键、用structuredclone或object.create(null)、升级依赖并启用--disable-proto=throw。

原型链污染不是代码写错,而是 JavaScript 运行机制被恶意利用的结果。它的危险性在于:一次污染,全局生效——所有普通对象都会意外继承被注入的属性。
底层成因:原型链查找机制 + 不受控的属性赋值
JavaScript 访问属性时,会按顺序查找:对象自身 → __proto__ 指向的原型 → 原型的 __proto__ → …… 直到 Object.prototype,最后是 null。这个机制本为继承服务,但一旦攻击者能让代码执行类似 target[key] = value 且 key === "__proto__",就等于直接往 Object.prototype 上写属性。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 常见污染入口:JSON.parse('{"__proto__": {"isAdmin": true}}') 后直接合并进配置对象
- 深拷贝/合并函数(如旧版 lodash.merge、_.set)未过滤敏感键名,把
__proto__当普通字段处理 - 手动递归赋值逻辑中,未校验 key 是否为
constructor、prototype或大小写变体(如__PROTO__)
关键防御手段:冻结 + 过滤 + 替代 + 隔离
单一措施无法兜底,需分层设防:
-
启动即冻结原生原型:在应用加载最早期(如 Node.js 的入口文件第一行、浏览器
<script></script>最顶部)执行Object.freeze(Object.prototype),同时冻结Array.prototype、Function.prototype等。严格模式下污染会抛错,非严格模式下静默失败,均能阻断 -
输入必须清洗或白名单校验:对所有外部数据(URL 参数、表单、JSON、HTTP Body),在解析后、合并前,移除或拒绝
__proto__、constructor、prototype及其大小写/编码变体 -
用安全替代方案代替通用合并:避免
lodash.merge处理不可信数据;浅拷贝优先用Object.assign({}, input);深拷贝可用structuredClone(input)(现代环境),或自定义函数跳过原型相关键 -
配置对象改用 null 原型:声明配置时不用
{},而用Object.create(null)。它没有__proto__,天然免疫污染,且不继承toString、hasOwnProperty等方法,反而更干净
运行时加固建议
防御不止于编码习惯,还需环境级防护:
- Node.js 启动时添加
--disable-proto=throw参数,强制拦截任何对__proto__的赋值操作 - 升级依赖至已修复版本:lodash ≥ 4.17.21、hoek ≥ 5.0.3;检查项目中所有深拷贝/合并类工具是否已知存在 CVE
- 对关键对象(如全局配置、用户上下文)做运行时监控,例如用 Proxy 包裹
Object.prototype,记录非常规属性写入行为
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










