关键在于阻断__proto__动态篡改原型链的生效路径,需从提交、构建、打包三阶段设防:提交阶段用语义扫描识别等价表达并拦截赋值;构建阶段锁定依赖、禁用危险polyfill;打包阶段做ast校验与运行时防护。

要拦截通过 __proto__ 动态篡改原型链绕过安全检查的恶意补丁,关键不是“检测某行代码有没有写 __proto__”,而是阻断其在构建与运行时生效的路径。2026年主流前端CI/CD已将此类原型污染(Prototype Pollution)列为高危供应链攻击入口,需从代码提交、构建依赖、打包产物三阶段设防。
提交阶段:强制静态扫描 + 原型污染语义识别
在 Git 钩子和 PR 检查中集成支持原型污染模式识别的扫描器,不止匹配字面量 __proto__,还需识别等价表达:
- 使用 TruffleHog v4.12+ 启用
--rules prototype-pollution-extended,可识别obj.constructor.prototype、Object.getPrototypeOf(obj).constructor、["__proto__"]动态属性访问等变体 - 配置 ESLint 插件 @typescript-eslint/no-prototype-builtins 并启用
enforceForClassMembers: true,拦截类方法内对this.__proto__或constructor.prototype的赋值 - 禁止在
package.json的scripts中调用含eval、Function或字符串拼接对象键的构建命令(如node -e "require('./patch').inject()")
构建阶段:锁定依赖 + 禁用危险 polyfill
很多原型污染利用发生在构建时被注入的 polyfill 或 loader 中,必须切断传播链:
- 禁用所有自动注入
core-js、es6-promise等旧版 polyfill 的构建插件(如 webpack 的babel-preset-env默认useBuiltIns: 'usage'),改用显式导入 + 手动白名单控制 - 在
webpack.config.js中设置module.rules显式拒绝匹配/__proto__/i或/constructor\.prototype/i的 require/import 调用(可通过自定义RuleSet插件实现) - 启用 npm audit --audit-level high --manual 并结合
oss-attribution工具生成 SBOM,对引入了lodash.merge、deepmerge等已知易受污染影响的包版本自动阻断
打包产物阶段:AST级校验 + 运行时防护注入
即使源码合规,压缩/混淆后仍可能暴露原型污染入口,需对最终 bundle 做二次审查:
- 在 CI 的 post-build 步骤调用 jscodeshift 运行自定义 codemod:
jscodeshift -t ./check-proto-pollution.js dist/main.*.js,遍历 AST 查找所有MemberExpression中property.name === '__proto__'或computed === true && property.type === 'Literal' && /__proto__/.test(property.value) - 向产出的 bundle 前置注入轻量运行时防护脚本(非全局 patch,仅作用于当前模块作用域):
if (Object.freeze) Object.freeze(Object.prototype);
该语句在 UMD/IIFE 包头执行,可拦截绝大多数基于__proto__的污染,且不影响现代 ES 模块的 tree-shaking - 对发布到私有 npm registry 的包,强制要求
publishConfig.access = "restricted"并开启registry.audit.enforce=prototype-pollution策略,由 registry 服务端在存储前做 AST 重检
这类防护不依赖开发者“别写 __proto__”,而是让写了也无效、传不进构建、跑不起来。2026年 SLSA Level 3 认证明确将原型污染拦截纳入“构建完整性门禁”必选项,配置到位后,一次 PR 就能触发全链路阻断。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











