最有效方式是页面加载最早期冻结核心原型链,即在首个内联script中调用object.freeze冻结object、array、function等原型,并用object.create(null)替代普通对象字面量,辅以构建与运行时监控及源头隔离措施。

直接冻结核心原型链是最有效的方式,不是靠事后检测或动态拦截,而是在页面加载最早期就切断篡改路径。
启动时立即冻结关键原型
所有防护动作必须在任何第三方脚本执行前完成,推荐放在 内首个内联 <script></script> 中:
- 调用
Object.freeze(Object.prototype),阻止新增、修改、删除任何属性 - 同步冻结
Array.prototype、Function.prototype、String.prototype、Boolean.prototype等常用原型(注意Math不是构造函数,无需处理) - 严格模式下篡改会抛出
TypeError;非严格模式下静默失败,仍可阻断攻击
用 Object.create(null) 替代普通对象字面量
避免因合并用户数据或第三方配置污染原型链:
- 凡用于存储映射、缓存、参数解析的“字典型”对象,一律改用
const map = Object.create(null) - 它不继承
Object.prototype,天然无toString、hasOwnProperty等方法,无法被原型污染波及 - 判断键存在时改用
Object.prototype.hasOwnProperty.call(map, key),而非map.hasOwnProperty(key)
构建与运行时双层监控
冻结是基础,但需配合可观测能力识别绕过或残留风险:
- 构建阶段:用
npm audit或oss-audit扫描依赖树,重点检查lodash、hoek、merge等已知存在原型污染漏洞的旧版本 - 运行时启动后注入检测逻辑,例如:
console.log(({}).toString === Object.prototype.toString),若返回false则说明已被篡改 - 对
Function.prototype.toString等关键方法做原生性校验:Function.prototype.toString.toString().includes('[native code]')
源头隔离高风险脚本
不信任即不加载,从加载环节物理隔绝污染可能:
- 禁用
eval、new Function()和内联javascript:协议 - 第三方脚本强制启用子资源完整性(SRI):
<script src="..." integrity="sha384-..."></script> - 敏感功能考虑沙箱化:
<iframe sandbox="allow-scripts"></iframe>加载,使第三方代码无法访问主环境原型链 - 配合严格的
Content-Security-Policy,禁用unsafe-eval和内联脚本











