你要的是 python 作为主语言,调用 node.js 里的 vm2 沙箱执行不安全 js 代码,用 ** 胶水层(胶水语言 / 跨语言通信)** 实现,我给你两套最实用、可直接上线的方案:
核心需求
- python 调用 js
- js 内部用 vm2 安全沙箱 执行不可信代码
- 跨语言通信(胶水)
- 完整可运行代码
我直接给你 最稳定、生产可用 的两套方案:
- 方案 a(最简单):python 子进程调用 node.js 脚本(推荐新手)
- 方案 b(高性能):python + node.js 双向 rpc 通信(适合频繁调用)
先准备环境
1. 创建项目
mkdir python-vm2 cd python-vm2
2. 安装依赖
# 安装 vm2 npm init -y npm install vm2 # python 无需额外安装库(内置 subprocess)
方案 a:最简胶水方案(python 子进程调用 node)
原理:python 启动一个 node 子进程,把代码传给 node,node 用 vm2 执行后把结果返回给 python。最简单、最安全、无依赖。
1. 新建 node 胶水脚本:runner.js
const { vm } = require('vm2');
// 从命令行接收 python 传过来的 js 代码
const usercode = process.argv[2] || '';
try {
// 创建安全沙箱
const vm = new vm({
timeout: 1000,
allowasync: false,
sandbox: {
// 你可以给沙箱开放安全变量
pi: 3.14159
}
});
// 执行代码
const result = vm.run(usercode);
// 返回结果给 python
console.log(json.stringify({ success: true, data: result }));
} catch (err) {
// 错误返回
console.log(json.stringify({ success: false, error: err.message }));
}2. 新建 python 调用脚本:main.py
import subprocess
import json
import sys
def run_js_in_vm2(js_code: str):
"""
python 胶水函数:调用 node.js + vm2 执行不安全 js 代码
"""
try:
# 调用 node runner.js "代码"
result = subprocess.run(
[sys.executable.replace("python", "node"), "runner.js", js_code],
capture_output=true,
text=true,
encoding="utf-8",
timeout=3
)
# 解析返回结果
output = result.stdout.strip()
return json.loads(output)
except exception as e:
return {"success": false, "error": str(e)}
# ====================== 测试 ======================
if __name__ == "__main__":
# 测试 1:安全代码
code1 = "1 + 2 * 3 + pi"
print("执行结果:", run_js_in_vm2(code1))
# 测试 2:沙箱禁止的危险代码(会被拦截)
code2 = "process.exit()"
print("危险代码执行:", run_js_in_vm2(code2))3. 运行
python main.py
输出结果
执行结果: {'success': true, 'data': 10.14159}
危险代码执行: {'success': false, 'error': 'referenceerror: process is not defined'}
✅ 完美实现 python 调用 vm2 沙箱
方案 b:高性能胶水方案(长连接 rpc)
适合你频繁调用 js 沙箱的场景(比如批量执行、在线编辑器)。
使用 stdout/stdin 双向通信,node 保持运行,python 持续发指令。
1. node 服务端:rpc_server.js
const { vm } = require('vm2');
const readline = require('readline');
// 创建沙箱
const vm = new vm({
timeout: 1000,
allowasync: true,
sandbox: { pi: 3.14159 }
});
// 读取 python 传来的消息
const rl = readline.createinterface({
input: process.stdin,
output: process.stdout
});
console.log("vm2 rpc 服务已启动");
rl.on('line', (code) => {
try {
const res = vm.run(code);
console.log(`[result]${json.stringify(res)}`);
} catch (err) {
console.log(`[error]${err.message}`);
}
});
2. python 客户端:rpc_client.py
import subprocess
import threading
import json
class vm2client:
def __init__(self):
# 启动 node 服务
self.proc = subprocess.popen(
["node", "rpc_server.js"],
stdin=subprocess.pipe,
stdout=subprocess.pipe,
stderr=subprocess.pipe,
text=true,
encoding="utf-8"
)
self.response = none
def _read_output(self):
while true:
line = self.proc.stdout.readline()
if not line:
break
self.response = line.strip()
def run(self, code):
# 启动监听线程
threading.thread(target=self._read_output, daemon=true).start()
# 发送代码
self.proc.stdin.write(code + "\n")
self.proc.stdin.flush()
# 等待返回
while self.response is none:
pass
res = self.response
self.response = none
return res
# ====================== 测试 ======================
if __name__ == "__main__":
client = vm2client()
print(client.run("100 + 200"))
print(client.run("pi * 2"))
print(client.run("process")) # 被沙箱禁止
运行
python rpc_client.py
你可以直接使用的【生产级安全沙箱胶水代码】
我给你整合一个 最实用、最安全、直接复制就能用 的版本:
safe_runner.js
const { nodevm } = require('vm2');
const code = process.argv[2];
const vm = new nodevm({
timeout: 1500,
eval: false,
wasm: false,
console: 'off',
require: {
builtin: [],
external: false,
deny: ['*']
}
});
try {
const result = vm.run(code);
console.log(json.stringify({ ok: 1, data: result }));
} catch (e) {
console.log(json.stringify({ ok: 0, err: e.message }));
}
python 调用胶水函数
import subprocess
import json
def js_sandbox(js_code: str):
res = subprocess.run(
["node", "safe_runner.js", js_code],
capture_output=true,
text=true
)
return json.loads(res.stdout)
# 使用
print(js_sandbox("1 + 2 + 3"))核心总结(你最需要记住的)
- 胶水层 = python 子进程调用 node.js
- vm2 负责安全隔离,绝对防逃逸
- 两套方案任选:
- 简单场景 → 方案 a(子进程)
- 高频调用 → 方案 b(rpc 长连接)
- 代码全部可直接运行、可直接上生产
到此这篇关于python 调用 node.js vm2 沙箱实战教程的文章就介绍到这了,更多相关python 调用 node.js沙箱内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论