JavaScript沙箱核心是可控执行而非禁止执行,需通过vm.Script+白名单上下文(Node.js)或iframe+srcdoc(浏览器)实现引擎级隔离,禁用原型链穿透和全局污染。

JavaScript 沙箱的核心目标不是“完全禁止执行”,而是“可控执行”
直接用 eval() 或 Function 构造函数运行第三方代码,等于把当前全局对象(window 或 globalThis)完全暴露出去——能读 localStorage、能发 fetch、能改 DOM、甚至能调 process.exit()(Node.js)。沙箱要解决的,是让一段代码只能访问你明确允许的 API,其余一律拦截或返回空/错误。
最轻量但有效的隔离:vm.Script(Node.js) + 严格上下文
Node.js 内置的 vm 模块提供基础能力,但它默认不自动隔离 I/O 和系统 API。关键在手动构造一个“裸”上下文:
const vm = require('vm');
const sandbox = {
console: { log: (...args) => console.log('[sandbox]', ...args) },
Math,
JSON,
// 注意:不传入 require、process、fetch、setTimeout 等
};
const script = new vm.Script('console.log("hello", Math.random());');
script.runInNewContext(sandbox); // ✅ 安全
// script.runInNewContext(globalThis); // ❌ 危险
-
runInNewContext是必须的,runInThisContext仍会污染当前作用域 -
sandbox对象里只放白名单属性;漏掉Array.prototype.push不要紧,但多加一个require就彻底失效 - 无法阻止原型链访问(如
{}.__proto__.constructor.constructor调eval),需配合vm.createContext+proxy进一步加固
浏览器端没有内置沙箱?那就用 iframe + srcdoc 隔离
现代浏览器中,iframe 是唯一被引擎级支持的 JS 隔离机制。它天然拥有独立全局对象、独立事件循环、独立存储空间:
const iframe = document.createElement('iframe');
iframe.sandbox = 'allow-scripts'; // 关键:禁用插件、表单提交、弹窗等
iframe.srcdoc = `









