原型污染是javascript中因不当操作object.prototype导致的安全漏洞,防范需避免不可信数据赋值、禁用易污染的递归合并、校验键名、使用object.create(null)、冻结原型及服务端输入清理。

原型污染是 JavaScript 中一种因不当操作对象原型(如 Object.prototype)而导致的严重安全问题,攻击者可通过构造恶意输入篡改原型属性,进而影响所有对象行为。防范核心在于:**避免将不可信数据直接用于对象属性赋值,尤其禁用递归合并、深拷贝等易污染原型的操作,同时主动防御原型属性写入**。
禁止向原型写入任意属性
许多工具函数(如 merge、deepAssign)在未过滤键名时,会把 "__proto__" 或 "constructor.prototype" 当作普通路径处理,导致污染。例如:
merge({}, { "__proto__": { "isAdmin": true } }); // 所有对象 now isAdmin === true
✅ 防范方式:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 使用白名单校验键名,显式拒绝
"__proto__"、"constructor"、"prototype"等敏感字符串 - 优先使用
Object.assign({}, ...)替代自研合并逻辑;若必须深合并,选用已修复的库(如lodash.mergev4.17.21+,内置原型防护) - 对用户输入做严格 schema 校验,不接受包含双下划线或点号的字段名
使用 Object.create(null) 创建纯净对象
默认对象继承自 Object.prototype,天然具备被污染风险。当需要纯字典/映射结构(如配置缓存、请求参数解析结果)时:
- 用
const map = Object.create(null);初始化,它不继承任何原型方法,map.__proto__为undefined,无法被污染 - 注意:此类对象无
toString、hasOwnProperty等方法,需改用Object.prototype.hasOwnProperty.call(map, key)判断属性存在性
冻结关键原型与启用严格模式
虽不能完全阻止污染(如通过 constructor.prototype 绕过),但可提升攻击门槛:
- 应用启动时执行
Object.freeze(Object.prototype);,阻止新增/修改属性(现代 Node.js 和浏览器支持) - 搭配
"use strict";使用,使向只读原型赋值抛出TypeError,而非静默失败 - 注意:已有污染无法清除,冻结应在任何第三方库加载前完成
服务端特别防护:验证与清理输入
前端可控性低,服务端才是最后防线:
- 对 JSON 解析后的对象,递归检查每个键是否为敏感原型字段,遇到即拒绝整条请求
- 使用
JSON.parse(str, (key, val) => key === "__proto__" ? undefined : val)在解析阶段剥离危险键 - 对配置类接口(如 Webhook 设置、模板变量注入),强制要求字段名符合 /^[a-z][a-z0-9_]*$/ 正则,排除特殊字符
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










