You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node服务端编译运行字符串形式的JavaScript代码并获取结果

现有方案的问题

你当前使用new Function的实现仅能在本地测试使用,完全不适合线上生产环境:new Function创建的函数可以直接访问服务端进程的全局作用域,恶意用户可通过提交代码调用process、fs等原生模块,执行删除文件、窃取敏感配置、发起网络攻击等操作,会直接导致你的服务被入侵。

基于Node.js vm模块的实现方案

vm是Node.js官方提供的原生沙箱模块,支持将用户代码和主进程的全局作用域隔离,你可以自定义控制暴露给用户代码的变量和接口,安全性和可控性远高于new Function方案,参考实现如下:

const vm = require('vm');

/**
 * 运行用户提交的JS代码
 * @param {string} userCode  用户提交的源代码
 * @param {any} testInput 测试用例输入
 * @returns 运行结果
 */
function runJudgeCode(userCode, testInput) {
  // 自定义沙箱上下文,仅暴露允许用户访问的内容
  const sandboxContext = {
    input: testInput,
    // 自定义console实现,收集用户代码的打印日志
    console: {
      log: (...args) => sandboxContext.runLogs.push(args.join(' '))
    },
    runLogs: []
  };

  // 包装用户代码,按题目要求调用对应的实现函数
  const wrappedCode = `
    (function(input) {
      ${userCode}
      // 假设题目要求参赛者实现名为solve的函数,直接调用获取返回值
      return solve(input);
    })(input)
  `;

  try {
    // 在沙箱中运行代码,设置超时和内存限制避免资源被占满
    const runResult = vm.runInNewContext(wrappedCode, sandboxContext, {
      timeout: 3000, // 单条用例最长运行3秒
      memoryLimit: 10 * 1024 * 1024 // 限制最大内存使用10MB
    });

    return {
      isPass: true,
      output: runResult,
      logs: sandboxContext.runLogs
    };
  } catch (err) {
    return {
      isPass: false,
      errorMsg: err.message,
      logs: sandboxContext.runLogs
    };
  }
}

// 测试示例
console.log(runJudgeCode(`function solve(n) { return n * n; }`, 5));
// 输出:{ isPass: true, output: 25, logs: [] }

额外安全优化建议

  • vm模块仍存在沙箱逃逸的可能性,如果你的服务是公开对外运营的,建议额外增加容器级隔离:每次收到代码提交就启动一个独立的轻量化Docker容器运行代码,运行结束后立即销毁容器,完全和主服务的运行环境隔离。
  • 绝对不要给沙箱上下文暴露process、fs、http等Node.js原生模块,所有用户可访问的变量都需要手动做白名单控制。
  • 可根据题目难度调整超时和内存限制,避免用户提交死循环或内存泄漏代码耗尽服务器资源。

内容的提问来源于stack exchange,提问作者Sajeeb Ahamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:45:04