应冻结原生原型对象并禁用原型污染操作:在应用初始化最早阶段用object.freeze()锁定string、number等关键原型;对所有外部输入做__proto__/constructor/prototype键名过滤;优先使用object.create(null)创建无原型对象;权限校验必须由后端完成。

直接改内置构造函数的原型(比如 Promise.prototype.then、Object.prototype)会破坏 JavaScript 引擎的优化机制,导致属性访问退化为动态查找,引发性能抖动;更严重的是,它可能被用于原型污染攻击,篡改全局行为,绕过权限校验或注入恶意逻辑。管控的关键不是“能不能改”,而是“谁改、改什么、什么时候改”。
冻结关键原型,阻断运行时修改
在应用初始化最早阶段(第三方脚本加载前),用 `Object.freeze()` 锁定原生原型对象,让后续任何覆盖或新增操作失效: -执行顺序必须靠前:放在 `<script>` 标签最顶部,或通过模块入口第一行代码运行</script>
-覆盖常用原型:String.prototype、Number.prototype、Boolean.prototype、Array.prototype、Object.prototype、Function.prototype
-注意:Object.freeze() 不影响已有属性值,但能阻止新增、删除和重配置;严格模式下非法修改会抛错,非严格模式下静默失败
拒绝污染式对象操作
所有来自外部的数据(JSON 解析结果、URL 参数、表单提交、API 响应)都视为不可信输入,禁止未经清洗就递归合并或赋值: -禁用 _.merge、_.set、deepAssign 等默认允许写入 __proto__ 的工具函数
对每个键名做正则匹配:/\b(__proto__|constructor|prototype)\b/i,不仅检查顶层,还要扫描嵌套路径(如 a.__proto__.b)
优先用 Object.assign({}, input) 浅拷贝;需深拷贝时,现代环境用 structuredClone(input),它天然跳过原型键
用无原型对象替代普通空对象
当你只需要一个纯数据容器(如缓存 Map、配置字典、路由参数解析结果),不要用{}:
- 改用 Object.create(null) 创建对象,它没有 __proto__,不继承 toString、hasOwnProperty 等方法,从根源切断污染路径
需要调用原生方法时,显式借用:Object.prototype.hasOwnProperty.call(obj, key)
适合插件注册表、状态映射表、临时上下文等“只存数据、不带行为”的场景
权限逻辑绝不依赖前端原型状态
攻击者可在控制台直接执行Object.prototype.isAdmin = true 或注入污染 payload,前端一切基于原型的判断都不可信:
- 角色、权限、按钮可见性等,仅作为服务端下发的渲染指令;前端不做决策,只做映射
-敏感操作(删除、导出、支付)必须携带完整上下文(如资源 ID、操作类型)向后端发起独立鉴权请求
-后端鉴权要查“该用户对这个具体资源是否有此操作权”,而非简单比对角色字符串
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











