不能靠检查__proto__结构来防止原型链污染,因为污染发生时__proto__只是被写入恶意属性而非结构改变,防御关键在于阻断用户输入对__proto__、constructor等敏感键的递归赋值,并在输入入口、赋值逻辑和对象创建环节落实过滤、安全替代与运行时加固。

不能靠检查 __proto__ 结构来防止原型链污染——这本身就是一个误解。污染发生时,__proto__ 并不会“变结构”,而是被意外写入了恶意属性;等你看到它、检查它时,污染早已完成,且可能已影响全局行为。
真正有效的防御不是事后检查,而是阻断污染路径
原型链污染的本质是:用户可控输入(如 JSON、URL 参数、表单数据)未经过滤就递归赋值到普通对象,最终触发对 __proto__、constructor.prototype 等敏感键的写入。防御核心在于“不给写入机会”,而非“看它有没有被写”。
必须过滤的敏感键名
所有递归操作(merge、set、assign、深拷贝)前,需显式拦截以下键名:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
"__proto__""constructor""prototype"-
"__proto__"的 Unicode 变体(如"__proto__".replace(/o/g, 'ο'))
用安全替代方案代替危险操作
避免手写或使用存在缺陷的工具函数:
- 用
structuredClone()替代JSON.parse(JSON.stringify())或 lodash.cloneDeep - 用
Object.assign({}, source)做浅合并时,先用Object.keys(source).filter(k => !isSensitiveKey(k))过滤 - 深合并逻辑中,每层遍历前都校验 key 是否在敏感列表中,直接跳过或报错
加固运行时环境
从根源上限制原型被修改的可能性:
- 启动时执行
Object.freeze(Object.prototype)(注意:部分 Node.js 版本支持,生产环境需测试兼容性) - 创建配置对象时优先用
Object.create(null),使其无原型,彻底规避继承污染 - 对关键对象(如 config、options)启用
Object.seal()或Object.freeze(),阻止新增/修改属性
总之,检查 __proto__ 不是防护手段,它既不可靠也无时效性。防护要落在输入入口、赋值逻辑和对象创建三个环节,做到“不接收、不传播、不继承”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










