原型污染漏洞源于javascript原型链机制,攻击者通过未校验的用户输入(如{"__proto__":{"isadmin":true}})递归赋值污染object.prototype,导致所有对象继承恶意属性;防范需三层面协同:冻结原生原型、使用object.create(null)、过滤敏感键名并升级安全api。

原型污染漏洞产生于 JavaScript 对象属性访问时沿原型链向上查找的机制,当代码未经校验地将用户可控输入(如 JSON、URL 参数、表单数据)递归赋值到对象上,就可能意外写入 __proto__、constructor 或 prototype 等敏感键,从而污染 Object.prototype。一旦污染成功,所有普通对象都会继承恶意属性,轻则逻辑错乱,重则触发 XSS、权限提升甚至远程代码执行。
污染是怎么发生的
核心路径是“不可信输入 → 未过滤键名 → 递归赋值 → 修改原型”:
- 攻击者提交类似
{"__proto__": {"isAdmin": true}}的 JSON,被服务端直接JSON.parse()后传入合并函数 - 老旧版本的
lodash.merge、_.set或手写深拷贝逻辑未跳过__proto__,执行了target[key] = value - 引擎将
__proto__视为普通属性名,实际却触发对Object.prototype的修改 - 后续任意空对象
{}都会拥有isAdmin === true,验证逻辑被绕过
关键防范手段
防御不是靠单一措施,而是运行时、数据流、依赖三层面协同:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
-
冻结原生原型:在应用最开始执行
Object.freeze(Object.prototype),同时冻结Array.prototype、Function.prototype等。严格模式下污染操作立即报错,非严格模式也静默失败 -
用无原型对象替代
{}:配置、参数、模板上下文等场景改用Object.create(null)创建对象,它没有__proto__,天然不参与原型链查找 -
过滤或拦截敏感键名:对所有外部输入,在解析或赋值前检查键是否为
"__proto__"、"constructor"、"prototype"及其大小写变体;深合并时需在每一层递归中做该检查 -
升级并替换危险 API:确保
lodash >= 4.17.21,避免使用已知有缺陷的深拷贝库;Node.js 17+ 优先用structuredClone();前端可考虑Object.assign({}, input)做安全浅拷贝
修复已有漏洞的实操建议
发现污染漏洞后,不能只打补丁,要系统性收口:
- 扫描项目中所有调用
merge、deepAssign、set、extend的位置,确认是否处理用户输入 - 检查
package-lock.json,锁定 lodash、hoek、merge-deep 等高危依赖版本,移除未维护的深拷贝工具 - 对解析 JSON 的接口加中间件:用正则或
JSON.parse的reviver函数剔除敏感键,例如:JSON.parse(jsonStr, (k, v) => k === '__proto__' ? undefined : v) - 在 Node.js 启动脚本中加入
--disable-proto=throw参数(仅限支持版本),强制拦截任何__proto__访问
不复杂但容易忽略










