diff --git a/src/lib/tool/ToolSandbox.js b/src/lib/tool/ToolSandbox.js index 3f03afd..16f03cd 100644 --- a/src/lib/tool/ToolSandbox.js +++ b/src/lib/tool/ToolSandbox.js @@ -207,9 +207,12 @@ class ToolSandbox { * 在基础沙箱中分析工具 */ async analyzeToolInSandbox() { - const basicSandbox = this.createBasicSandbox(); + const sandbox = this.createSandbox({ + supportDependencies: false, + sandboxPath: process.cwd() + }); const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` }); - const context = vm.createContext(basicSandbox); + const context = vm.createContext(sandbox); try { script.runInContext(context); @@ -442,7 +445,10 @@ class ToolSandbox { * 创建执行沙箱环境 */ async createExecutionSandbox() { - this.sandboxContext = this.createSmartSandbox(); + this.sandboxContext = this.createSandbox({ + supportDependencies: true, + sandboxPath: this.sandboxPath + }); // 在智能沙箱中重新加载工具 const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` }); @@ -459,19 +465,27 @@ class ToolSandbox { } /** - * 创建基础沙箱 + * 创建统一沙箱环境 + * @param {Object} options - 沙箱配置 + * @param {boolean} options.supportDependencies - 是否支持依赖解析 + * @param {string} options.sandboxPath - 沙箱工作目录 + * @returns {Object} 沙箱环境对象 */ - createBasicSandbox() { + createSandbox(options = {}) { + const { + supportDependencies = false, + sandboxPath = process.cwd() + } = options; + return { - require: require, + require: supportDependencies ? + this.createSmartRequire(sandboxPath) : + this.createAnalysisRequire(), module: { exports: {} }, exports: {}, console: console, Buffer: Buffer, - process: { - env: process.env, - hrtime: process.hrtime - }, + process: this.createProcessMock(sandboxPath), setTimeout: setTimeout, clearTimeout: clearTimeout, setInterval: setInterval, @@ -491,48 +505,70 @@ class ToolSandbox { } /** - * 创建智能沙箱(支持依赖) + * 创建完整的process对象mock + * @param {string} sandboxPath - 沙箱工作目录 + * @returns {Object} mock的process对象 */ - createSmartSandbox() { + createProcessMock(sandboxPath) { return { - require: (moduleName) => { - try { - // 优先从沙箱目录查找依赖 - return require(require.resolve(moduleName, { - paths: [ - path.join(this.sandboxPath, 'node_modules'), - this.sandboxPath, - process.cwd() + '/node_modules' - ] - })); - } catch (error) { - // 回退到默认require + env: process.env, + version: process.version, + platform: process.platform, + arch: process.arch, + hrtime: process.hrtime, + cwd: () => sandboxPath, + pid: process.pid, + uptime: process.uptime + }; + } + + /** + * 创建分析阶段的mock require + * 让所有require调用都成功,脚本能完整执行到module.exports + * @returns {Function} mock require函数 + */ + createAnalysisRequire() { + return (moduleName) => { + // Node.js内置模块使用真实require + const builtinModules = ['path', 'fs', 'url', 'crypto', 'util', 'os', 'events', 'stream']; + + try { + // 检查是否是内置模块 + if (builtinModules.includes(moduleName) || moduleName.startsWith('node:')) { return require(moduleName); } - }, - module: { exports: {} }, - exports: {}, - console: console, - Buffer: Buffer, - process: { - env: process.env, - hrtime: process.hrtime - }, - setTimeout: setTimeout, - clearTimeout: clearTimeout, - setInterval: setInterval, - clearInterval: clearInterval, - Object: Object, - Array: Array, - String: String, - Number: Number, - Boolean: Boolean, - Date: Date, - JSON: JSON, - Math: Math, - RegExp: RegExp, - Error: Error, - URL: URL + } catch (e) { + // 内置模块加载失败,继续mock处理 + } + + // 第三方模块返回通用mock对象 + console.log(`[ToolSandbox] 分析阶段mock模块: ${moduleName}`); + return new Proxy({}, { + get: () => () => ({}), // 所有属性和方法都返回空函数/对象 + apply: () => ({}), // 如果被当作函数调用 + construct: () => ({}) // 如果被当作构造函数 + }); + }; + } + + /** + * 创建支持依赖解析的require函数 + * @param {string} sandboxPath - 沙箱路径 + * @returns {Function} 智能require函数 + */ + createSmartRequire(sandboxPath) { + return (moduleName) => { + try { + return require(require.resolve(moduleName, { + paths: [ + path.join(sandboxPath, 'node_modules'), + sandboxPath, + process.cwd() + '/node_modules' + ] + })); + } catch (error) { + return require(moduleName); + } }; }