原型链查找本身非漏洞,但沙箱未冻结object.prototype等核心原型并隔离__proto__、constructor时,攻击者可污染原型、劫持方法逃逸沙箱;需在脚本执行前用object.freeze()递归冻结关键原型,proxy拦截__proto__/constructor访问,并重写object.getprototypeof等api阻断隐式查找。

原型链查找特性本身不是漏洞,但它是前端沙箱逃逸中被高频利用的“桥梁”。当沙箱未切断不可信代码对宿主原型对象(尤其是Object.prototype、Function.prototype、Array.prototype等)的读写能力时,攻击者可通过污染原型、劫持内置方法或构造隐式调用链,绕过沙箱限制,最终访问全局对象、执行任意代码或提升权限。
彻底冻结关键原型对象
仅靠删除属性或重写toString等方法远远不够。必须使用Object.freeze()递归冻结整个原型链起点:
- 在沙箱初始化阶段,立即冻结
Object.prototype、Function.prototype、Array.prototype、String.prototype等核心原型——注意:需在任何用户脚本执行前完成 - 冻结后,再通过
Object.preventExtensions()和Object.seal()加固子对象,防止新增属性或修改已有属性描述符 - 示例:
Object.freeze(Object.prototype); Object.freeze(Function.prototype);(需在沙箱全局上下文创建前注入)
隔离并重定义__proto__与constructor
这两个属性是原型链操控的“开关”,必须从沙箱内对象中移除或重定向:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- 为所有注入沙箱的原始对象(如
window、document的代理对象)设置__proto__为null,或返回一个空、冻结的伪造原型 - 将
constructor属性设为只读且不可枚举,避免通过{}.constructor.constructor回溯到Function构造器 - 若使用
Proxy实现沙箱,get拦截器必须显式捕获__proto__和constructor访问,并返回安全默认值
禁用隐式原型访问路径
攻击者常借助instanceof、isPrototypeOf()、Object.getPrototypeOf()甚至for...in遍历触发原型链查找。需主动阻断:
- 重写
Object.getPrototypeOf,使其对沙箱内对象一律返回null或空对象 - 覆盖
instanceof操作符行为:在沙箱全局中将Symbol.hasInstance设为undefined,或通过Proxy拦截构造函数的该符号 - 对传入沙箱的对象做深度代理,确保其
toString、valueOf等可能触发原型链的方法不泄露宿主环境信息
监控与拒绝动态原型污染尝试
即使做了冻结,部分引擎(尤其旧版V8)在特定条件下仍允许间接污染。建议增加运行时防护:
- 在沙箱执行前,快照
Object.prototype等关键对象的属性名列表与描述符(Object.getOwnPropertyDescriptors()),执行后比对是否新增/修改 - 对
Object.setPrototypeOf、__proto__ =赋值、Reflect.setPrototypeOf等操作统一拦截并抛出错误 - 若沙箱基于
iframe,启用sandbox="allow-scripts"但**禁用allow-same-origin**,从根本上切断原型链跨域污染可能
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










