真正安全、轻量、可落地的前端微沙箱,核心在于用最小必要手段达成全局变量隔离、危险API屏蔽、原型链污染免疫三项刚性目标:以Object.create(null)打底切断原型链,Proxy拦截get/set/has/ownKeys四类操作,显式绑定执行上下文,并按需注入冻结的纯函数能力。

不需要“完全不依赖标准库”,也不需要追求“超强现代化”这种模糊目标。真正安全、轻量、可落地的前端微沙箱,核心在于用最小必要手段达成三项刚性目标:全局变量隔离、危险 API 屏蔽、原型链污染免疫。所有过度设计(比如重写 Date/Array/JSON)反而引入新漏洞。
用 Object.create(null) 打底,彻底切断原型链
这是防御原型链污染最根本的一环。真实 window 对象自带 toString、valueOf、hasOwnProperty 等方法,恶意代码可通过 Object.prototype.__proto__ = null 以外的方式篡改原型链,或利用隐式调用触发副作用。而 Object.create(null) 创建的对象没有 [[Prototype]],连 in 操作符和 for...in 都无法遍历到任何继承属性:
- 父沙箱 = Object.create(null),然后只挂载你明确信任的能力,比如 sandbox.console = { log() { /* 安全输出 */ } }
- 子沙箱 = Object.create(父沙箱),自动继承只读能力,但所有新增属性(如 sandbox.a = 1)都落在子沙箱自身,不影响父级
- 禁止直接操作 Object.prototype、Function.prototype 或 Array.prototype —— 不是靠“检测”,而是从基座上就不存在它们
Proxy 拦截必须覆盖 get/set/has/ownKeys 四个关键 trap
仅靠原型继承无法阻止写入污染,也无法隐藏敏感属性。Proxy 是不可绕过的控制层:
- get:先查自身,再查原型;对 eval、document、location、fetch、XMLHttpRequest 等一律返回 undefined 或 throw new Error('Forbidden')
- set:强制 receiver === target,杜绝 proxy.target.x = y 向原型链赋值;所有写入只作用于当前子沙箱对象
- has 和 ownKeys:确保 Object.keys(sandbox)、for (let k in sandbox) 只返回子沙箱自身属性,不暴露父沙箱挂载的只读能力(避免被枚举后篡改)
执行上下文必须显式绑定,禁用一切隐式 this
脚本若以普通函数方式执行,this 默认指向 globalThis 或真实 window,立刻逃逸隔离。必须切断这一路径:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
立即学习“前端免费学习笔记(深入)”;
- 用 new Function('sandbox', 'return (function(){' + code + '}).call(sandbox)') 包装用户代码
- 执行时传入的是 Proxy 封装后的子沙箱对象,不是原始 fakeWindow
- 在代码解析阶段做 AST 或正则扫描,拒绝含 with 语句的代码(with 会动态改变作用域链,Proxy 无法可靠拦截)
按需注入能力,绝不暴露原始全局对象
所谓“不依赖标准库”,不等于不用浏览器原生能力。关键是受控使用:
- 需要 Date.now?挂 sandbox.Date = { now: () => Date.now() },而不是 sandbox.Date = Date
- 需要 fetch?封装成 sandbox.fetch = (...args) => safeFetch(...args),内部校验 URL 白名单、禁止 credentials: 'include'
- 需要 JSON?挂 sandbox.JSON = { parse: JSON.parse, stringify: JSON.stringify },不暴露原型方法
- 所有注入能力都应是纯函数或冻结对象,禁止返回可修改的引用(如 document.createElement 返回的 DOM 节点必须被拦截或代理)
不复杂但容易忽略。

















