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

Node环境下安全执行不可信字符串代码的可行方案探讨

Node环境安全执行不可信字符串代码的方案

场景说明

我用Node开发的应用,通过axios抓取HTML页面,经htmlparser2解析后将有效信息转为JSON格式返回给前端JS应用。页面中包含一段创建数组的JavaScript代码,我需要获取该数组的数据。目前有两种处理思路:

  1. 自行编写解析器提取所需信息(可行但实现复杂);
  2. 直接执行这段字符串形式的JS代码以获取数组值。

Node官方文档明确提示node:vm模块并非安全机制,不可用于运行不可信代码,而我获取的这段代码属于不可信范畴,因此想了解对应的安全执行方案。

附目标脚本片段:

hatizsakCucc = new Array();
hazbanCucc = new Array();
function adatokMessage(targyIndexStr,tomb) {
    var targyIndex = parseInt(targyIndexStr);
    if (tomb.length<1) alert("Nincs semmi!");
    else alert(tomb[targyIndex]);
}

hatizsakCucc[0]="Név: ezüst\nSúly: 0.0001 kg.\nMennyiség: 453\nÖsszsúly: 0.0453 kg.\n";
hatizsakCucc[1]="Név: kaja\nSúly: 0.4 kg.\nÁr: 2 ezüst\nMennyiség: 68\nÖsszár: 136 ezüst\nÖsszsúly: 27.2 kg.\n";
hatizsakCucc[2]="Típus: fegyver\nNév: bot\nSúly: 2 kg.\nÁr: 6 ezüst\nMin. szint: 1\nMaximum sebzés: 6\nSebzés szórás: 5\nFajta: ütő/zúzó\n";
hatizsakCucc[3]="Típus: fegyver\nNév: parittya\nSúly: 0.3 kg.\nÁr: 14 ezüst\nMin. szint: 1\nMaximum sebzés: 7\nSebzés szórás: 4\nFajta: távolsági\n";
hatizsakCucc[4]="Név: csodatarisznya\nSúly: 4 kg.\nÁr: 1000 ezüst\nExtra: templomi árú\n";
hatizsakCucc[5]="Név: imamalom\nSúly: 5 kg.\nÁr: 150 ezüst\nExtra: templomi árú\n";

我已通过正则表达式hatizsakSzkript.match(/hatizsakCucc(.*)\\n/g);提取出hatizsakCucc数组的内容,后续会将数组元素解析为如下结构的对象:

{
    nev: "ezüst",
    suly: 0.0001,
    mennyiseg: ...
}

但仍好奇在Node环境中安全执行不可信字符串代码的可行方案。

安全执行方案

使用专业沙箱库

可以使用vm2这类基于Node vm模块增强的沙箱库,它提供了更严格的隔离机制,能限制代码对宿主环境敏感资源的访问,同时支持设置超时避免恶意代码阻塞进程。示例代码:

const { VM } = require('vm2');
const vm = new VM({
    timeout: 1000, // 限制代码执行超时时间
    allowAsync: false, // 禁止执行异步代码
    sandbox: {} // 仅提供空沙箱环境,按需暴露必要全局对象
});

try {
    const targetArray = vm.run(`
        hatizsakCucc = new Array();
        hatizsakCucc[0] = "Név: ezüst\\nSúly: 0.0001 kg.\\nMennyiség: 453\\nÖsszsúly: 0.0453 kg.\\n";
        hatizsakCucc[1] = "Név: kaja\\nSúly: 0.4 kg.\\nÁr: 2 ezüst\\nMennyiség: 68\\nÖsszár: 136 ezüst\\nÖsszsúly: 27.2 kg.\\n";
        hatizsakCucc; // 返回目标数组
    `);
    console.log(targetArray);
} catch (err) {
    console.error('代码执行出错:', err);
}

严格管控原生vm模块的执行上下文

如果使用Node原生vm模块,必须手动严格限制执行上下文,仅暴露绝对必要的全局变量,同时禁用所有敏感API。示例:

const vm = require('vm');
// 仅提供必要的全局构造函数,避免暴露敏感对象
const context = {
    Array: Array
};

try {
    const script = new vm.Script(`
        hatizsakCucc = new Array();
        hatizsakCucc[0] = "Név: ezüst\\nSúly: 0.0001 kg.\\nMennyiség: 453\\nÖsszsúly: 0.0453 kg.\\n";
        hatizsakCucc;
    `);
    // 在新上下文执行,设置超时防止死循环
    const result = script.runInNewContext(context, { timeout: 1000 });
    console.log(result);
} catch (err) {
    console.error('执行错误:', err);
}

注意:原生vm模块仍存在潜在的逃逸风险,仅适合对代码来源有一定信任度的场景,优先级低于专业沙箱库。

代码预处理+白名单校验

通过AST解析工具(如acorn)对目标代码片段进行语法分析,只允许白名单内的语法和操作(比如仅允许数组赋值、字符串字面量,禁止函数定义、循环、全局对象访问等)。这种方式安全性最高,但实现复杂度较大,适合已提取出目标代码片段的场景,可针对性地做语法校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:55:18