重点是__proto__本身不绕过表单审查,而是作为跳板污染Object.prototype,导致校验环境异常;防御需四步:一、最早执行Object.freeze(Object.prototype)等冻结核心原型;二、表单配置改用Object.create(null)替代{};三、所有外部输入递归清洗__proto__/constructor/prototype键;四、校验函数前做原型完整性检查或隔离运行。

直接说重点:__proto__ 隐式修改本身不会绕过表单格式审查,真正危险的是它被用作“跳板”,污染 Object.prototype 后让后续所有对象(包括表单校验逻辑中创建的临时对象、配置对象、甚至校验函数自身)行为异常或被劫持。 表单硬性审查失效,往往不是规则被绕过,而是执行审查的代码环境已被污染。
下面分四个关键环节讲清楚怎么防:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
一、冻结核心原型,从源头掐断污染能力
表单校验逻辑若依赖普通对象(如 { rules: [...] } 或 new FormData() 后处理的对象),一旦 Object.prototype 被污染,这些对象就可能意外继承恶意属性或方法。
- 在页面
<script>最顶部(早于任何第三方脚本、框架初始化、表单组件加载)执行:Object.freeze(Object.prototype); Object.freeze(Array.prototype); Object.freeze(Function.prototype);
- 注意:冻结必须在任何用户脚本运行前完成。如果用了 React/Vue 等框架,需确保该代码在框架 runtime 加载前执行(例如放在
index.html的首个<script>中)。
二、校验对象创建时主动弃用 {},改用无原型容器
表单配置、规则映射、字段缓存等纯数据容器,别再用 {} —— 它天然继承 Object.prototype,是污染传导的“高速公路”。
- 替换为:
const formRules = Object.create(null); // 没有 __proto__,没有 toString,无法被污染 const fieldCache = Object.create(null);
- 使用时注意兼容:
- 判断键存在 →
Object.prototype.hasOwnProperty.call(obj, key) - 获取键数组 →
Object.keys(obj)仍可用(Object.create(null)本身不阻止Object.keys) - 不要调用
obj.toString(),它会报错;需要字符串表示时用JSON.stringify(obj)
- 判断键存在 →
三、表单解析与合并环节严格过滤敏感键名
攻击者常通过 JSON 提交、URL 参数、富文本插入等方式注入 {"__proto__": {"required": true}} 这类 payload,一旦被 JSON.parse() 后直接合并进校验配置,就会触发污染。
- 所有外部输入进入校验逻辑前,做递归清洗:
- 匹配正则
/^(?:__proto__|constructor|prototype)$/i - 对每个 key 名和嵌套路径(如
a.b.__proto__.c)都检测 - 发现即剔除整层,不递归、不保留、不警告——静默丢弃
- 匹配正则
- 避免使用
_.merge、_.set处理用户输入;优先用:- 浅拷贝:
Object.assign({}, userInput) - 深拷贝(现代环境):
structuredClone(userInput)
- 浅拷贝:
四、校验函数自身做运行时完整性保护
如果攻击者已提前污染了 Function.prototype.toString 或 Object.prototype.hasOwnProperty,你的校验函数可能在不知情下返回错误结果。
- 在关键校验函数执行前加轻量校验:
if (typeof Object.prototype.hasOwnProperty !== 'function' || Object.prototype.hasOwnProperty.toString().indexOf('[native code]') === -1) { throw new Error('Prototype integrity check failed'); } - 更稳妥做法:把核心校验逻辑封装进
<iframe sandbox="allow-scripts">或 Web Worker,物理隔离原型环境,确保校验器永远运行在洁净上下文中。
不复杂但容易忽略。

















