- Terrarium 是一个基于 Pyodide 的 Python 沙箱,可部署在 Cloud Run 上,旨在以低成本和可接受的延迟运行不受信任的代码。
- 该环境提供基于调用的隔离、对多个科学库的支持,并通过虚拟文件系统处理输入和输出文件。
- 其架构结合了 WebAssembly、Node.js、Docker 和 Cloud Run 来隔离代码,但已发现稳定性和服务健康管理问题。
- 严重漏洞 CVE-2026-5752 允许以 root 权限执行代码,目前没有计划发布补丁,因此建议评估缓解措施和替代方案。

当我们讨论运行不受信任或由人工智能生成的 Python 代码时,最大的挑战之一是如何安全、快速地完成,同时又不至于在基础设施上投入巨资。正是在这种背景下,Cohere AI 推出了 Terrarium,这是一个沙箱解决方案,旨在为在云端(尤其是 Google Cloud Run)部署的容器中托管和运行此类代码而设计。
这种方法使得开发者和公司能够以合理的成本和相当不错的性能,将 Terrarium 用作部署用户代码或 LLM 模型的隔离环境。然而,随着时间的推移,一些非常严重的漏洞也逐渐浮出水面,其中一个漏洞的 CVE 编号暴露了沙箱安全性的重大缺陷,使 Terrarium 成为舆论焦点。
什么是生态瓶?它的设计用途是什么?
Terrarium 本质上是一个独立的 Python 运行时环境,设计为可部署的 Docker 容器,例如,可以在 Google Cloud Run 上部署。它的主要目的是提供一个沙箱环境,用于部署潜在的危险或未知代码(例如用户提交的脚本或语言生成的代码片段),而不会直接危及主基础设施的安全。
该项目的设计理念是提供价格合理、低延迟且易于集成到现有工作流程中的服务。Terrarium 的设计初衷是通过 HTTP 请求调用,发送待执行的 Python 代码(以及可选的输入文件),并接收执行结果以及生成的文件。
实际上,这意味着外部系统、API 甚至内部工具都可以将 Python 代码的执行委托给 Terrarium,从而将该代码保持在一个相对封闭的环境中,并对资源、执行时间和允许的功能制定明确的规则。
Terrarium 的一个关键设计特点是它依赖于Pyodide,Pyodide 是一个在 Node.js 进程中执行的 CPython 到 WebAssembly 的构建工具。这种方法意味着 Python 代码并非在宿主系统上直接运行,而是在一个封装的解释器中运行,理论上增强了其隔离性。
沙箱的性能、成本和主要特性
Terrarium 的最大卖点之一是其低运营成本和可接受的性能。在 Google Cloud Run 上的实际部署中,典型的配置为 2 GB 内存、1 个 vCPU 和至少一个始终在线且支持按需自动扩展的实例,内部标注阶段的月成本约为 30 美元。
就速度而言,上述测试表明,Terrarium 可以生成例如200 dpi 的简单 matplotlib 图表的 PNG 图像,耗时约 900 毫秒;或者生成 SVG 版本,耗时约 500 毫秒。这些时间指的是托管在 Cloud Run 上的代码,包括该服务的典型调用周期。
除了性能之外,Terrarium 还拥有调用之间完全隔离的特性。每次调用后,沙箱都会被完全回收:Pyodide 的虚拟文件系统、全局变量、已加载的库以及所有内部状态都会被丢弃。这样做的目的是防止任何调用继承先前执行的数据或上下文,从而降低信息泄露的风险。
另一点也很重要,尽管Cohere的目标是实现强大的隔离,但它明确表示并不对沙箱的完整性提供绝对保证。这暗示着,即使有多层保护,仍然存在发现漏洞的可能性,尤其是在像WebAssembly及其与Node.js集成这样复杂的环境中。
Terrarium 的设计旨在方便其他服务调用:只需向部署在 Cloud Run 上的端点发送 HTTP 请求,并附上要执行的代码和授权令牌(如果配置需要)。作为回报,您将收到一个包含结果的 JSON 文件,以及(如果适用)以 base64 编码的生成文件。
Pyodide 中的文件执行和库支持
Terrarium 的一个吸引人的特点是它能够原生处理输入输出文件。其 API 允许将任意类型的多个文件与 Python 代码一起附加到请求中;这些文件会被放置在 Pyodide 向 Python 解释器公开的虚拟文件系统中。
在执行过程中,Python 代码可以像操作本地文件一样读取和操作这些文件。执行完成后,Terrarium 会收集所有已创建或修改的文件,并将它们作为响应返回给客户端,通常会进行编码以便通过 HTTP 无缝传输。
关于库生态系统,由于 Terrarium 基于 Pyodide,因此继承了一套相当广泛的科学和数据分析软件包。直接支持的软件包包括:numpy、pandas、matplotlib、sympy、beautifulsoup4、python-sat、scikit-learn、scipy 和 sqlite3(后者默认情况下未启用,但可以根据需要选择加载)。
就 matplotlib 而言,存在一些限制:plt.show() 在此环境下不受支持,但只要不强制使用过多的参数(例如极高的分辨率,这会增加资源使用量),使用 plt.savefig() 生成图像就能正常工作。
这套库使得 Terrarium 在数据分析、可视化、机器学习模型原型设计和结构化信息操作等任务中特别有用,所有这些操作都在理论上可控的沙箱中执行。
内部架构:多层隔离和部署
Terrarium 的架构采用多层结构,旨在尽可能缩小攻击面并隔离不受信任的代码。第一层是 Node.js 进程本身,它充当宿主并加载 Pyodide,即编译成 WebAssembly 的 CPython。
用户提交的 Python 代码会在 WebAssembly 环境中进行解析、编译和执行,而不是在宿主机系统上直接执行。这种方式从根本上限制了代码的功能,因为 Pyodide 使用内存中的虚拟文件系统,无法直接访问宿主机磁盘,也没有传统的后台处理能力。
其中最相关的限制包括:无法访问真实文件系统(只能访问 Pyodide 的内部虚拟文件系统)、完全不支持线程和多进程、无法启动子进程、无法访问运行 Node.js 的主机的内存、调用之间无法共享状态(因为整个环境都会重启),以及出于设计考虑,无法访问网络或互联网。最后一个限制原本是出于设计考虑,未来可能会进行修改,但最初却引发了更多争议。
第二层隔离在于云部署本身:Node.js 进程运行在 Docker 容器内,该容器部署在 Google Cloud Run 上。这不仅限制了运行时间和可用资源,而且在假设的沙箱遭到入侵的情况下,还能将运行代码的容器与组织基础设施的任何其他部分解耦。
总而言之,Terrarium 的原始设计依赖于WebAssembly、Docker 和 Cloud Run的组合来构建一个相对安全的 Python 执行环境,通过一系列屏障来阻止程序从沙箱逃逸到主机系统和内部网络。
本地部署、Docker 部署和 Google Cloud Run 部署
要在开发环境中使用 Terrarium,必须在机器上安装 Node.js。满足此要求后,通常的步骤包括安装项目依赖项并运行本地服务器,以及处理代码执行请求的函数。
服务器运行后,可以向本地端点发送请求以传输测试文件和 Python 脚本,从而允许开发人员在部署到生产环境之前验证沙箱的行为。脚本可用于对测试目录中的所有 .py 文件运行一系列测试,从而简化环境验证。
在容器化环境中,Terrarium 可以构建为 Docker 镜像,并作为独立容器运行。典型的指令包括构建、运行和停止步骤,以及用于查找正在运行的容器标识符并在需要时手动管理它的命令。
Terrarium 迁移到 Google Cloud Run 后,被部署为可自动扩展的 HTTP 服务,并可配置资源和并发参数。建议调整这些值以平衡性能、成本和安全性。例如,对于密集型工作负载,可以分配更多 CPU 和内存,并限制每个实例的并发数以防止阻塞。
需要注意的是,当 Pyodide 配置为 Terrarium 时,它会在主 Node.js 进程中运行。这意味着,如果您的 Python 代码资源占用过高或进入复杂的循环,可能会阻塞 Node.js 响应其他请求的能力。Pyodide 建议在需要中断或进一步隔离执行的情况下使用 Workers,但这种方法会使集成变得复杂,并且在某些情况下会限制对 matplotlib 等库的支持。
卫生服务管理和稳定性问题
在 Google Cloud Run 上部署时,实际挑战之一是监控服务健康状况和从崩溃中恢复。Cloud Run 默认情况下不支持使用 Dockerfile 中的 HEALTHCHECK 定义健康检查,因此需要进行一些额外的调整。
通常的步骤是使用 gcloud 描述 Cloud Run 服务,并将配置导出到 service.yaml 文件。在该 YAML 文件中,添加了一个与容器镜像关联的 livenessProbe 配置,以便 Cloud Run 能够检测到服务何时停止正常响应。
配置修改完成后,现有服务被替换为相应的 gcloud 命令,以便 Cloud Run能够主动监控容器状态,并在实时检查失败时重启容器。此操作仅在首次使用该特定镜像部署新服务时需要。
在纯 Docker 层面,还存在一个额外的限制:Docker 引擎本身并不提供仅基于 HEALTHCHECK 的自动重启功能。此外,容器中 PID 为 1 的进程受到特别保护,难以从容器内部终止。因此,在某些环境中,会考虑使用诸如 docker-autoheal 之类的第三方工具,这些工具可以监控容器的健康状况,并在检测到问题时强制重启。
关于执行稳定性,团队观察到,在处理特别繁重的工作负载时,Pyodide 中频繁出现“RangeError: Maximum call stack size exceeded”之类的错误。这种情况在使用 matplotlib 生成 PNG 图片时采用极高的 dpi 值,或者执行特别复杂的 pandas 操作时更为常见,这表明 WebAssembly 环境内部的堆栈管理存在限制。
Terrarium 中存在严重漏洞 CVE-2026-5752
随着时间的推移, Terrarium 中发现了一个严重漏洞,编号为 CVE-2026-5752,CVSS 评分为 9,3。这种严重程度表明该缺陷可能对使用此沙箱的系统安全造成极其严重的影响。
该漏洞允许攻击者在宿主进程中以 root 权限执行任意代码。攻击途径依赖于 Pyodide WebAssembly 环境中的恶意原型链遍历,从而有效绕过沙箱限制。
最令人担忧的是,利用此漏洞无需任何特殊权限或额外的用户交互。攻击者只需将代码注入沙箱(例如,通过利用使用 Terrarium 的工具中的代码执行功能),即可利用此漏洞逃离受控环境。
一旦被利用,该漏洞可能允许未经授权访问敏感系统文件,例如/etc/passwd 或其他内部容器资源,甚至可能根据整体安全配置,将权限提升到主机或共享同一基础架构的其他服务。
这种情况对所有使用 Terrarium 作为用户代码或 AI 模型执行环境的组织构成重大风险。这不仅仅是理论上的漏洞,而是沙箱被攻破可能导致数据泄露、内部服务受损以及网络内横向移动的现实情况。
对企业、开发者和最终用户的影响
该漏洞的发现直接影响到任何已将Terrarium 集成到其基础架构中以运行不受信任的 Python 代码的公司或开发人员。如果协作开发工具、学习平台、按需分析服务或基于 AI 的代码辅助产品使用 Terrarium 作为运行时层,则可能会受到威胁。
从最终用户的角度来看,风险不仅在于服务提供商的基础设施可能受到损害,还在于如果攻击者设法利用该漏洞,存储在这些平台上的个人或职业信息可能会在事先没有通知的情况下被泄露或篡改。
由于Terrarium 已停止维护,情况变得更加复杂。这意味着官方不会发布补丁修复此问题,导致继续依赖该解决方案的组织面临已知漏洞且无法获得支持的风险。
在这种情况下,继续使用 Terrarium 而不采取额外措施会带来相当大的安全风险。了解攻击途径的攻击者可以专门针对继续使用该技术的服务,寻找系统整体安全漏洞。
此外,在多个服务共享同一内部网络甚至同一容器集群的环境中,Terrarium 的泄漏可能会打开向其他看似隔离的系统横向移动的大门,从而放大成功攻击的潜在影响。
可考虑的缓解策略和替代方案
鉴于如此严重的安全漏洞以及缺乏积极的维护,我们首先建议各组织机构紧急评估其当前对 Terrarium 的使用情况。如果 Terrarium 用于运行第三方代码或 AI 模型生成的代码,则风险更大,需要立即采取行动。
短期措施包括暂时禁用生产环境中允许执行任意代码的功能,同时评估更安全的替代方案。其他选项包括加强网络策略、进一步隔离使用 Terrarium 的服务,以及限制其他系统对容器的访问。
从中长期来看,迁移到其他沙箱或隔离执行解决方案可能更为明智,这些方案应具备积极的维护机制,并有社区或服务提供商提供支持以修复漏洞。这可能包括托管服务、具有更严格限制的无服务器执行环境,或专门设计为默认安全的微服务架构。
总之,此次事件凸显了将良好的安全实践融入开发生命周期的重要性:定期进行依赖性审计、审查架构中使用的第三方组件、监控相关的 CVE,以及在检测到严重故障时制定快速响应计划。
构建允许最终用户运行或生成代码的 AI 工具的公司应该仔细分析其沙箱的设计,确保隔离流程保持最新,并避免依赖废弃的项目来实现运行不受信任代码等敏感功能。
Terrarium 的方方面面都体现了运行用户代码和 LLM 模型对极致安全的要求。高性能、低成本的沙箱环境看似极具吸引力,但如果出现无法修复的严重漏洞,这种平衡就会被打破,对于许多严肃的应用场景而言,风险将变得不可接受。
