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 等方式绕过,回溯到全局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),通信仍可能被利用Content-Security-Policy 不是沙箱,而是补充防线CSP 控制的是资源加载行为(如禁止内联脚本、限制 fetch 目标域名),它不阻止已加载的 JS 代码执行任意逻辑 —— 如果你的沙箱里允许运行用户代码,而 CSP 又没限制 script-src 'unsafe-eval',那等于开门揖盗。
script-src 值为 'self' 时,eval 和 new Function 会被直接拒绝(除非显式加 'unsafe-eval')iframe sandbox 无影响;反过来,iframe sandbox 也不执行 CSP 规则(它是独立文档上下文)iframe sandbox 隔离执行 + 父页面用 CSP 限制自身资源加载 + 通信时严格校验 event.source 和 event.origin
下面这个 iframe 不会读取当前页面 Cookie,不能调用 alert,也无法访问 localStorage(除非显式开启 allow-same-origin,但那样就失去意义):
如果需要传数据进来,必
须用 postMessage,且沙箱内脚本要主动监听;返回数据也一样 —— 所有通信路径都得显式设计、显式校验。
沙箱真正的复杂点不在“怎么启动”,而在于“边界怎么划、数据怎么流、错误怎么降级”。哪怕用了 vm2 或 iframe,只要通信接口设计松散、输入没清洗、输出没约束,就只是给攻击者提供了更隐蔽的入口。