如果你运营一个在线编程教育平台或代码评测系统,一定遇到过这个难题:如何安全地运行用户提交的代码?传统的做法是使用Docker容器,但资源消耗大、启动慢。本文介绍一种更轻量的方案——使用MicroPython和WebAssembly(WASM)搭建Python代码沙箱。
为什么选择WASM沙箱?
与传统Docker方案相比,WASM沙箱有以下优势:
启动速度快:WASM模块可以在毫秒级启动,而Docker容器通常需要秒级。
资源消耗低:WASM运行在浏览器或独立的运行时中,内存占用远低于完整的容器环境。
安全性高:WASM默认运行在沙箱环境中,无法访问文件系统和网络,天然适合运行不受信任的代码。
跨平台:WASM可以在任何支持的运行时中运行,无需考虑操作系统差异。
MicroPython简介
MicroPython是Python 3的精简实现,专门为微控制器和嵌入式环境设计。它保留了Python的核心语法和大部分标准库,但移除了一些重量级模块(如完整的socket库、多线程支持等)。
MicroPython可以编译为WASM,这意味着你可以在浏览器或WASM运行时中执行Python代码,而且不需要安装完整的Python环境。
搭建步骤
步骤一:准备MicroPython WASM版本
首先,你需要获取MicroPython的WASM编译版本。可以从官方仓库下载预编译版本,或自行编译:
# 克隆MicroPython仓库
git clone https://github.com/micropython/micropython.git
cd micropython
# 编译WASM版本
make -C ports/webassembly
步骤二:创建HTML宿主页面
创建一个HTML页面来加载和运行MicroPython WASM:
<!DOCTYPE html>
<html>
<head>
<title>Python Sandbox</title>
</head>
<body>
<textarea id="code" rows="10" cols="80">
print("Hello from sandbox!")
for i in range(5):
print(f"Count: {i}")
</textarea>
<br>
<button onclick="runCode()">Run</button>
<pre id="output"></pre>
<script src="micropython.wasm"></script>
<script>
async function runCode() {
const code = document.getElementById('code').value;
const output = document.getElementById('output');
// 创建独立的MicroPython实例
const mp = await loadMicroPython();
// 重定向stdout
let result = '';
mp.setStdout((data) => {
result += new TextDecoder().decode(data);
});
try {
mp.runPython(code);
output.textContent = result;
} catch (e) {
output.textContent = 'Error: ' + e.message;
}
}
</script>
</body>
</html>
步骤三:添加资源限制
为了防止恶意代码消耗过多资源,需要添加执行时间限制和内存限制:
// 设置执行超时(例如5秒)
const TIMEOUT = 5000;
async function runCodeWithTimeout(code) {
return Promise.race([
executePython(code),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Execution timeout')), TIMEOUT)
)
]);
}
步骤四:扩展为服务端方案
如果你需要在服务端运行WASM沙箱,可以使用wasmtime或wasmer运行时:
# 安装wasmtime
curl https://wasmtime.dev/install.sh -sSf | bash
# 运行MicroPython WASM
wasmtime micropython.wasm --dir /tmp
安全注意事项
虽然WASM沙箱天然具有隔离性,但仍需注意以下安全问题:
1. 资源限制:必须设置执行时间和内存使用限制,防止DoS攻击。
2. 输出过滤:过滤用户代码的输出,防止XSS攻击(如果输出显示在网页上)。
3. 文件系统隔离:确保WASM实例无法访问主机文件系统。
4. 网络隔离:默认情况下WASM无法访问网络,但需要确保运行时配置正确。
适用场景
这种方案特别适合以下场景:
• 在线编程教育平台:学生可以直接在浏览器中运行Python代码
• 代码评测系统:安全地运行和测试用户提交的代码
• 交互式文档:在文档中嵌入可运行的Python示例
• 低代码平台:让用户通过Python脚本自定义业务逻辑
对于站长而言,WASM沙箱提供了一种安全、高效、低成本的方式来运行不受信任的代码。如果你的网站需要这个功能,不妨试试MicroPython + WASM的方案。
本文参考来源:Simon Willison: Running Python in a WASM sandbox with MicroPython


















暂无评论内容