直接在控制台运行object.prototype.polluted='test';console.log({}.polluted==='test'),若输出true则已污染;需结合object.isfrozen(object.prototype)确认是否被冻结。

怎么用浏览器控制台快速验证页面是否已受原型污染
直接在开发者工具 Console 里运行检测语句,是最快确认当前页面是否已被污染的方式。它不依赖构建流程或源码访问,适合线上环境即时判断。
执行以下代码:
Object.prototype.polluted = 'test'; const testObj = {}; console.log(testObj.polluted === 'test');
如果输出 true,说明 Object.prototype 已被污染——这不是 lodash 版本问题,而是已有恶意脚本或漏洞函数(如 _.merge、_.defaultsDeep)被执行过。
常见干扰项:
- 某些调试工具或旧版 polyfill 会主动设置
__proto__属性,但不等于污染了Object.prototype;关键看新建对象能否继承非标准属性 - 若页面使用了
Object.freeze(Object.prototype),上述检测会静默失败,需额外检查是否被冻结:Object.isFrozen(Object.prototype)
哪些 HTML 中嵌入的 JS 调用最容易触发原型污染
原型污染不是 HTML 本身的问题,而是 HTML 中内联或引入的 JavaScript 脚本调用了不安全的深度操作函数。重点排查以下三类写法:
-
<script>_.merge({}, JSON.parse(decodeURIComponent(location.search.slice(1))))</script>—— URL 参数解析后直接进_.merge,攻击者可传?__proto__[isAdmin]=true -
<script>const config = {...window.INIT_DATA, ...userInput}</script>—— 展开运算符在对象层级较深时等价于不安全递归赋值,尤其当userInput来自localStorage或location.hash -
<script src="vendor.js"></script>加载了含漏洞版本的lodash@ 或 <code>lodash-es@,且后续有任意一处调用 <code>_.set、_.update、_.defaultsDeep
注意:_.assign 和 _.extend 不会深度遍历,相对安全;但 _.merge 和 _.defaultsDeep 是高危主力。
HTML 页面中如何定位污染源头的 JS 代码段
污染往往发生在页面初始化阶段,源头代码通常具备两个特征:接收外部输入 + 调用深度合并函数。排查时优先盯住这些位置:
- 所有对
location.search、location.hash、document.referrer的解析逻辑,尤其是紧跟JSON.parse后立即传给_.merge的链式调用 - 从
<script type="application/json"></script>标签中读取配置的代码,例如JSON.parse(document.getElementById('config').textContent),若之后用于_.defaultsDeep就危险 - 第三方 SDK 初始化脚本(如埋点、A/B 测试),它们常内部使用
lodash处理传入的 options 对象,而你无法控制其输入来源
技巧:在 Sources 面板全局搜索 _.merge、_.defaultsDeep、JSON.parse 和 location.,再人工串联调用上下文。不要只看函数名,要看它的参数是不是动态拼接出来的。
修复时为什么不能只升级 lodash 版本
升级到 lodash@4.17.21+ 确实修复了已知 CVE-2023-26116,但仅靠版本升级远远不够——因为污染可能来自你自己写的等效逻辑,或其它库的类似函数。
真正要做的有三件事:
- 禁用所有对
__proto__、constructor.prototype、prototype字符串路径的写入:可在_.merge前加校验,或改用更安全的替代方案如structuredClone(现代环境)或JSON.parse(JSON.stringify())(浅层) - 对所有用户输入做白名单过滤:比如只允许
{user: {name, email}}这样的固定结构,拒绝任何带__proto__、constructor键名的对象 - 冻结基础原型(防御性措施):
Object.freeze(Object.prototype)应放在所有脚本执行前,最好作为<script></script>第一行;但注意这会影响部分老库,需充分测试
最易被忽略的一点:服务端返回的 JSON 数据如果被前端无条件 _.merge 到全局状态,那污染入口根本不在 HTML 里,而在 API 响应中——这种跨层信任才是真正的盲区。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











