JavaScript沙箱是人为构造的受限执行上下文,非浏览器内置安全区;eval和Function仍可访问全局对象,iframe sandbox+srcdoc或vm2才是可靠方案,需配合CSP与严格postMessage校验。

JavaScript 沙箱环境不是浏览器内置的“安全隔离区”,而是一种**人为构造的受限执行上下文**,它本身不提供绝对安全,关键看你怎么构建和使用它。
沙箱 ≠ 自动安全:为什么 eval 或 Function 构造函数直接执行代码仍然危险
很多人误以为把代码塞进一个新函数作用域就是沙箱。但 eval 和 new Function(...) 默认仍能访问全局对象(如 window、document、fetch),只要代码里写 fetch('/api') 或 localStorage.setItem,照样能跑。
- 默认情况下,
new Function('return this')()返回的就是window(浏览器)或globalThis(Node.js) - 即使你删掉
this,代码仍可通过Object.getPrototypeOf({}).constructor等方式绕过,回溯到全局 - 现代浏览器对内联脚本有 CSP 限制,但沙箱逻辑若在允许范围内(比如
unsafe-eval开了),就完全失效
真正可用的轻量级沙箱:用 vm2(Node.js)或 iframe + srcdoc(浏览器)
自己手写“安全”沙箱几乎必然漏洞;生产环境应依赖经过审计的方案。
-
vm2是目前 Node.js 中最常被采用的沙箱库,它重写了require、拦截原型链访问、禁用process.binding等底层能力,比原生vm模块更严格 -
浏览器端最可靠的是
:sandbox属性默认禁用 DOM 访问、表单提交、弹窗、插件等,且srcdoc内脚本无法访问父页面window - 注意:
iframe沙箱中parent和top是受限制的,但若父页主动暴露window.postMessage接口,且没校验来源(event.origin),通信仍可能被利用
常见误判点:CSP、Content-Security-Policy 不是沙箱,而是补充防线
CSP 控制的是资源加载行为(如禁止内联脚本、限制 fetch 目标域名),它不阻止已加载的 JS 代码执行任意逻辑 —— 如果你的沙箱里允许运行用户代码,而 CSP 又没限制 script-src 'unsafe-eval',那等于开门揖盗。
立即学习“Java免费学习笔记(深入)”;
- CSP 的
script-src值为'self'时,eval和new Function会被直接拒绝(除非显式加'unsafe-eval') - 但 CSP 对
iframe sandbox无影响;反过来,iframe sandbox也不执行 CSP 规则(它是独立文档上下文) - 真正起效的组合是:
iframe sandbox隔离执行 + 父页面用 CSP 限制自身资源加载 + 通信时严格校验event.source和event.origin
一个最小可行的 iframe 沙箱示例(浏览器端)
下面这个 iframe 不会读取当前页面 Cookie,不能调用 alert,也无法访问 localStorage(除非显式开启 allow-same-origin,但那样就失去意义):
如果需要传数据进来,必须用 postMessage,且沙箱内脚本要主动监听;返回数据也一样 —— 所有通信路径都得显式设计、显式校验。
沙箱真正的复杂点不在“怎么启动”,而在于“边界怎么划、数据怎么流、错误怎么降级”。哪怕用了 vm2 或 iframe,只要通信接口设计松散、输入没清洗、输出没约束,就只是给攻击者提供了更隐蔽的入口。











