![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/5-1721905295.png)
摘要
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/7-1721905295.png)
随着大模型的快速发展,各种各样的AI应用层出不穷。其中有一类AI应用允许用户通过代码执行特定的任务。AI应用通过执行代码极大的扩展了其使用场景,既能够完成简单的计算任务执行,也能够完成复杂的业务数据分析。
AI应用的代码执行需要运行在安全沙箱中,比如OpenAI的代码解释器(code interpreter)就使用了gVisor作为其安全沙箱。安全沙箱是一个古老而现代的话题,计算任务的隔离始终是计算机领域的的刚需。当前业界的AI研究以及AI应用中代码执行能力的研究大部分在其使用场景上,对于其后面的代码执行沙箱环境缺乏必要的关注与研究。AI应用如果允许用户执行代码,那么这些代码就可能是来自攻击者的恶意代码。如果代码执行沙箱的隔离做得不好,攻击者就能够攻破AI应用的后端服务,对整个集群带来巨大的安全风险。
蚂蚁天宸安全实验室在AI安全技术研究的过程中发现,目前AI和LLM应用中涉及的攻击技术已经有不少发现与成果,但是AI 应用中的代码执行环境的安全防御并未引起业界专家重视。本文通过测试分析多个AI应用的代码执行沙箱实现方案,并以ChatGPT 4为例介绍了我们的测试方法,最后总结出类似场景的沙箱方案选型及沙箱安全策略建议。
1
背景
AI应用厂商通常有两种方式提供给用户执行代码。第一种方式为代码解释器,用户可以通过自然语言与AI应用交互,AI应用通过与LLM交互获取执行的代码并执行来完成用户任务;第二种方式允许用户编写自己的代码作为AI应用中的一个工具来完成用户的任务。本文将不区分这两种代码执行情形,对于任何用户能够编写代码并且执行的场景我们都认为其为AI应用中的代码执行功能。
OpenAI面世之初,大量安全研究人员通过和 ChatGPT进行简单对话,即可让它反弹shell 到攻击者指定服务器,并进行进一步内网渗透。随后,ChatGPT变成了“纯语言模型,不能运行代码”:
但随着ChatGPT 4的推出,OpenAI重新提供了代码解释器的功能,并且能够帮用户运行自定义代码。例如:
ChatGPT 4的代码解释器功能再次推出,OpenAI 充分吸取了此前的经验,不仅在语义层对代码意图进行了分析,会尝试拦截恶意代码运行,同时也提供了可靠隔离的沙箱运行环境,会将用户代码运行在一个独立隔离的沙箱环境中,杜绝恶意代码对OpenAI自身服务或其他用户造成影响。
经过我们的分析,ChatGPT 4的语义分析限制很容易绕过,但ChatGPT 4会将每个用户的任务运行在一个独立隔离的容器中,并且使用了谷歌开源的安全容器gVisor[1]作为容器runtime ,从而缓解Docker隔离性不足的问题。网络层面,每个容器有一个独立IP,彼此间无法互通,东西向访问内网和南北向访问互联网均进行了安全限制,只能有限通信。OpenAI的这套沙箱方案经过国内外安全研究人员的测试已经发展的较为可靠,但是业界其他提供code interpreter服务的AI应用依然存在较多问题。例如,我们在测试某些AI应用时,就发现其能够进行反弹shell,并且能够执行任意命令。
故此,我们对主流AI应用的代码执行沙箱方案进行了研究,发现各个应用的沙箱方案均不尽相同,下文阐述了我们的详细测试过程、总结出的沙箱发展趋势,以及同类应用的沙箱使用建议。
2
测试对象
为了给出AI应用的代码执行沙箱选型建议,我们需要首先分析当前主流AI应用使用的沙箱解决方案和安全策略有哪些。在沙箱测试过程中,我们主要测试如下内容:
01
是否能够执行任意命令。沙箱如果支持任意命令执行,那么攻击者能够执行的任意代码,其进行探测、攻击的能力会显著增强。
02
是否为特权用户执行。沙箱执行用户代码使用权限是否为特权用户(通常在 Linux 下为 root ),如果沙箱使用 root 执行用户代码,则攻击者能够完成更多的系统探测以及攻击手法。
03
是否支持访问外网。沙箱如果支持访问外网,则能够反弹 shell 到攻击者的机器,进而进行进一步的攻击。
04
是否做了东西向隔离。东西向隔离表明沙箱内的业务能否访问到其他沙箱实例的网络或者内部网络,如果沙箱未做东西向隔离,则攻击者能够攻击其他沙箱实例或者内网。
05
是否泄露了敏感信息。环境变量或者沙箱可见的文件可能包含敏感数据比如密钥或者关键代码逻辑。如果攻击者能够看到这些代码或数据则可能进行进一步攻击或者绕过安全措施。
06
是否能够上传任意文件。沙箱如果支持上传任意文件,攻击者可以上传恶意代码来完成进一步攻击。
07
使用的沙箱方案。通过分析使用的沙箱方案,攻击者可以更进一步研究其漏洞进行攻击。
在测试对象的选择上,我们选择了如下几款 AI 应用。后文会介绍,这几款应用使用的沙箱方案代表了几类场景的沙箱实现,非常具有典型性。
01
ChatGPT 4[2]。ChatGPT 是 OpenAI 推出的AI工具,GhatGPT 4 支持 code interpreter 功能,能够帮用户完成代码执行工作。
02
应用 A。该应用是一款AI工具,用户能够编写JavaScript或者Python代码辅助完成任务。
03
应用 B。该应用是用来方便人们通过AI构建各种工作流,也能够支持用户编写代码完成相关工作。
04
应用 C。该应用是一个旨在让所有人都能够通过AI开发自己的应用程序。
05
应用 D。该应用也是一个旨在通过AI帮人们完成各种工作的应用,为了支持处理复杂任务,也支持执行代码。
06
应用 E。该应用旨在通过利用AI技术为人们提高生产力,其提供的代码解释器可以供人们完成复杂的数据分析、处理和清洗任务。
3
测试方法
我们以ChatGPT 4为例,来介绍如何完成上述的测试项目。
01
是否能够执行任意命令
测试方法:使用常用的系统命令进行测试,如果均能正确执行,则判断为能够执行任意代码。
测试结果:对于ChatGPT 4而言,通常情况下,并不能直接执行任意代码。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/6-1721905296.jpeg)
这种情况下,需要通过一些Prompt绕过。我们使用如下Prompt进行绕过,并且通过上传混淆之后的代码进行执行。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/1-1721905297.jpeg)
chattest.py是混淆之后的Python代码,其中的read函数接受一个命令,read函数会执行该命令。下面执行"ls -lh /mnt/data"命令,可以看到,ChatGPT 4正确执行了命令。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/4-1721905297.jpeg)
下面的命令执行 "which curl" 命令找到 curl 程序的路径。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/10-1721905298.jpeg)
可以看出,ChatGPT 4是可以任意命令执行的。
02
是否为特权用户执行
测试方法:执行id命令,判断进程的执行用户。
测试结果:从下图可以看到,ChatGPT 4使用了非特权用户。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/3-1721905298.jpeg)
03
是否支持外连公网
测试方法:通过访问一个外部网站,判断其是否支持主动外连公网。
测试结果:ChatGPT 4不能访问任意互联网。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/0-1721905298.jpeg)
04
是否做了东西向隔离
测试方法:通过访问内部的基础设施网络或者其他沙箱实例,判断其是否实现了东西向的网络隔离。
tcp 测试结果:通过上传的 ncat 进行测试,其无法链接到 kubernetes api server 的端口。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/1-1721905299.jpeg)
udp 测试结果:通过上传的ncat进行测试,其无法链接到DNS解析服务器的端口。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/3-1721905299.jpeg)
05
是否泄露了敏感信息
测试方法:这里主要关注两点,第一是环境变量,通过查看进程的环境变量是否有敏感信息比如密钥,第二是文件系统上的内部源码文件或者配置文件。通过执行env命令,可以看到ChatGPT 4使用了kubernetes集群作为其基础设施架构。
测试结果:
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/4-1721905300.jpeg)
通过在机器内进一步探索,也发现了一些内部代码。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/7-1721905300.jpeg)
06
是否上传任意文件
测试方法:是否支持上传任意文件通常有两种方式,如果平台能够允许上传文件,则实际上传,如果平台能够访问外网则通过网络获取文件。对于ChatGPT 4而言,其不支持外网访问,但是支持文件上传。前面分析已经看到,可以上传任意文件。
测试结果:下面测试执行我们上传的文件。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/1-1721905301.jpeg)
/mnt/data/mybinary是我们上传的一个binary文件,其内容为打印"in my binary",可以看到,ChatGPT 4已经成功执行了我们的代码。
07
使用的沙箱方案
测试方法:判断沙箱使用的方案,通常需要组合几种方法。比如通过dmesg命令查看内核打印的数据,或者通过 ps/uname等命令查看系统信息,或者通过查看执行代码的用户,或者分析系统上相关的文件。
测试结果:通过执行dmesg命令,从第一行"Starting gVisor"可以看到ChatGPT 4使用了gVisor作为其代码执行沙箱。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/1-1721905301.jpeg)
4
整体测试结果
上一部分以ChatGPT 4为例详细介绍了测试步骤,本节给出我们筛选的AI应用的测试结果并且对其使用的沙箱进行简单分析与介绍。对于有风险的结果,我们对其进行了标红处理。
测试地址:https://openai.com/gpt-4,测试日期:2024年4月。
在“测试步骤”一节中已经详细进行了分析,这里再对测试结果进行总结。ChatGPT 4 测试结果如下:
· 是否能执行任意命令:是。
· 是否为特权用户执行:否。
· 是否支持访问外网:否。
· 是否做了东西向隔离:是。
· 是否泄露了敏感信息:是。
· 是否能够上传任意文件:是。
· 使用的沙箱方案:gVisor。
综上,通过分析,ChatGPT 4的代码执行是在gVisor安全容器中完成的。gVisor是Google开发的一款基于应用内核的安全容器,官网地址为https://gvisor.dev, 下一节将详细介绍其原理。
测试日期:2024年4月。
应用 A 测试结果如下:
· 是否能够执行任意命令:否。
· 是为特权用户执行:否。
· 是否支持访问外网:部分。能够发起 http/https 请求,但是无法使用底层网络能力。
· 是否做了东西向隔离:是。应用 A 的沙箱没有网卡,其网络请求是通过浏览器完成的。
· 是否泄露了敏感信息:部分。在 应用 A 的沙箱中能够看到其绑定的 Python 版本和相关库代码。
· 是否能够上传任意文件:是。
· 使用的沙箱方案:Pyodide。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/3-1721905301.jpeg)
综上,通过分析,应用 A 的代码执行是在 Pyodide 中运行的。Pyodide是基于WebAssembly的,能够在浏览器和 Node.js 执行的 Python 发行版,官网地址为https://pyodide.org,详细原理会在下一节介绍。
测试日期:2024年4月。
应用 B 测试结果如下:
· 是否能够执行任意命令:是。
· 是否为特权用户执行:否。
· 是否支持访问外网:是。
· 是否做了东西向隔离:是。
· 是否泄露了敏感信息:否。
· 是否能够上传任意文件:是。
· 使用的沙箱方案:Omegajail。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/9-1721905302.jpeg)
综上,应用B使用了Omegajail作为其安全沙箱。Omegajail是一款Linux下基于进程级的安全沙箱,其使用Linux的 namespace、cgroup、seccomp等机制构建一个受限的代码执行环境。
其官网地址为:
https://github.com/omegaup/omegajail
详细原理将在下一节介绍。
测试日期:2024年4月。
应用 C 测试结果如下:
· 是否能够执行任意命令:否。
· 是否为特权用户执行:是。
· 是否支持访问外网:部分。
· 是否做了东西向隔离:是。
· 是否泄露了敏感信息:是。
· 是否能够上传任意文件:是。能够通过 Typescript 或者 JavaScript 下载任意文件到文件系统。
· 使用的沙箱方案:Deno。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/2-1721905302.jpeg)
综上,应用C使用了Deno作为其代码执行沙箱。Deno是一个运行JavaScript和TypeScript的运行时环境,基于V8引擎采用rust构建,旨在提供一个高效、安全的脚本环境。Deno官网地址为https://deno.com, 详细原理会在下一节介绍。
测试日期:2024年4月。
应用 D 测试结果如下:
· 是否能够执行任意命令:是。
· 是否为特权用户执行:否。
· 是否支持访问外网:是。能够反弹shell出网。
· 是否做了东西向隔离:是。
· 是否泄露了敏感信息:是。能够读取部分业务源码。
· 是否能够上传任意文件:是。能够从外网下载任意文件到文件系统
· 使用的沙箱方案:Lambda(Firecracker)。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/4-1721905302.jpeg)
综上,应用D的代码执行是在aws的Lambda上执行的。Lambda的底层是Firecracker。Firecracker是一款基于KVM的虚拟机监控器(VMM),可以通过其创建轻量级虚拟机,这些虚拟机通常叫做microVM 。
其官网地址为https://firecracker-microvm.github.io,详细原理将在下一节介绍。
测试日期:2024年4月。
应用 E 测试结果如下:
· 是否能够执行任意命令:是。
· 是否为特权用户执行:否。
· 是否支持访问外网:是。能够反弹shell出网。
· 是否做了东西向隔离:是。
· 是否泄露了敏感信息:否。
· 是否能够上传任意文件:是。能够从外网下载任意文件到文件系统。
· 使用的沙箱方案:e2b[3]。沙箱的根目录有.e2b文件,而e2b是专门为AI应用提供代码执行沙箱的SDK。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/8-1721905303.jpeg)
综上,应用E使用了e2b沙箱服务,而e2b沙箱底层是基于Firecracker实现的。
小结
下面是对各个AI Agent的沙箱选型方案以及沙箱安全策略的总结。
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/10-1721905303.png)
从沙箱方案来看,Pyodide、Deno属于语言级别沙箱,omegaijail属于进程级别沙箱,Firecracker、gVisor属于系统级别沙箱,其中语言、进程、系统表明的是沙箱的隔离边界。从策略上看,大部分的沙箱都能够执行任意任意命令、能够访问外网、能够上传任意文件。大部分的沙箱都是非特权用户执行用户代码,并且做了东西向的隔离。
5
AI 应用常用沙箱技术分析
上一节测试了各个AI应用使用的沙箱方案以及其关键的安全策略。本节对这几个沙箱进行简单介绍。下一节会给出沙箱的使用建议。
Pyodide是基于WebAssembly的,能够在浏览器和 Node.js执行的Python发行版。Pyodide提供一个在浏览器中运行完整Python科学计算工具栈的环境。基本架构如下:
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/5-1721905304.jpeg)
图片参考:
https://www.whitphx.info/static/d2bd1a3747d59735aeac180e7da602f9/f058b/stlite_archtecture.002.png
Pyodide将CPython的源码和相关的科学计算包打包在一起,使用emscripten的编译器将它们编译为WebAssembly。并且引入emscripten的虚拟机文件系统,这些虚拟的文件驻留在浏览器内存中。
Pyodide能够完成常见的Python数据处理任务,但是对于一些复杂的功能无法支持。
Pyodide通常直接运行在浏览器中,能够受到浏览器安全沙箱的保护,所以整体上它的安全性是比较高的。
Pyodide能够完成常见的Python数据处理任务,但是对于一些复杂的功能无法支持。Pyodide通常直接运行在浏览器中,能够受到浏览器安全沙箱的保护。
Deno是一个运行JavaScript和TypeScript 的运行时环境,基于V8引擎采用rust构建,旨在提供一个高效、安全的脚本环境。其架构如下图:
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/10-1721905304.jpeg)
图片来自:
https://github.com/denoland/deno/blob/f96aaa802b245c8b3aeb5d57b031f8a55bb07de2/website/images/schematic_v0.2.png?raw=true
Deno使用Rust编写,通过启动V8引擎来运行JavaScript和TypeScript代码。Deno在初始化过程中会注册业务代码访问系统资源的回调,当业务代码进行网络、文件等操作时,会进入到Deno注册的回调中处理。
Deno的一个特点是,只能执行ECMAScript代码,默认没有任何访问权限,比如无法使用网络访问、读写文件系统等。
Deno本质上也是一种语言级别的执行环境,只能够执行ECMAScript相关的代码。
Omegajail是一款Linux下基于进程级的安全沙箱,其使用Linux的namespace、cgroup、seccomp等机制构建一个受限的代码执行环境。其架构如下:
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/2-1721905304.jpeg)
Omegaijail首先根将源码进行编译,然后创建运行环境,对编译之后的代码进行执行。
Omegajail跟nsjail等进程级沙箱有个不一样的地方是Omegajail不是从直接启动一个编译好的进程,而是从源码进行编译,然后执行。这导致Omegajail需要具备常见语言的编译与运行环境。如果业务需要特定的编译与运行环境,则无法满足。
Omegajail是一种进程级别的沙箱,其使用与宿主机共享的内核,也容易让恶意用户获取到宿主机的相关信息,甚至进行沙箱逃逸。
Firecracker是一款基于KVM的虚拟机监控器 (VMM),可以通过其创建轻量级虚拟机,这些虚拟机通常叫microVM。Firecracker 基本架构如下:
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/10-1721905305.jpeg)
图片来自:
https://files.gotocon.com/uploads/slides/conference_14/835/original/Firecracker%20Presentation%20GOTO%20AMS.pdf
Firecracker提供一个最简单的虚拟机环境,该虚拟机只有必要的若干设备,比如网卡、存储、时钟等。Firecracker同样使用 seccomp、cgroup等Linux原生安全机制对进程本身做限制。对于虚拟机中的操作系统,Firecracker使用了最小功能的内核,以提高性能。
Firecracker为LLM生产的代码提供了一个独立的虚拟机环境,通过两层的纵深防御提升了安全水位。AI应用可以通过直接调用Firecracker或者调用基于Firecracker的AWS Lambda服务来完成代码执行的功能。
gVisor是一款基于应用内核的容器运行时。gVisor使用Go语言编写,实现了常见的 Linux系统调用界面。gVisor本质上是一款轻量级的虚拟机,传统上跑在Linux上面的程序无需修改即可运行在gVisor中,其架构如下:
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/1-1721905305.jpeg)
图片来自:
https://gvisor.dev/docs/Layers.png
gVisor实现了两层纵深防御。应用程序在运行时如果需要执行系统调用,首先会进入 gVisor实现的内核Sentry,如果Sentry无法完成相关任务,才会调用宿主机的内核功能。Sentry进程安装了很多seccomp规则,无法直接调用宿主机内核的所有系统调用。
综上,gVisor使用内存安全语言、两层的纵深防御架构以及独立的内核、轻量级的特性。
使用gVisor作为代码执行沙箱有诸多优点:比如独立内核的强隔离特性、开源可定制、能够运行绝大多数Python程序。但是其缺点则是使用门槛高、性能损失可能会比较大。
6
沙箱选择建议
测试的这几种沙箱包括了主流的沙箱类型。从测试结果可以看出,出于使用场景、业务兼容性、接入成本的考量,目前业界并没有一个占压倒性优势的沙箱解决方案。下面从几个关键维度对上述沙箱方案进行总结:
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/5-1721905306.png)
我们将Pyodide和Deno归类为语言级沙箱,但是需要注意的是,这里的语言级沙箱跟传统的语言级沙箱不太一样。传统的语言级沙箱比如nodejs中的vm2,以及Java中的groovy沙箱,它们接收代码片段,然后运行。
Pyodide和Deno本质上并不是为沙箱而生的方案,Pyodide是Python的发行版,Deno是JavaScript和TypeScript的运行时,他们都通过其底层运行时实现了沙箱的功能,Pyodide通过将Python或JavaScript代码运行在 JavaScript的解释引擎中达到了沙箱的目的,Deno同样是为JavaScript和TypeScript代码提供了一个运行环境,并且在与宿主机的交互中需要显示指定安全策略而实现了沙箱功能。
通过上表以及本文的测试以及我们的调研,对于 AI 应用的沙箱选型,大致可以得出如下结论。
1) 从以上对比可以看出,进程级沙箱在大模型时代已经逐渐式微,而语言级别和系统级别沙箱则得到了新的青睐。
6个应用中,2个使用了语言级沙箱,3个使用了基于gVisor/Firecracker的系统级沙箱,只有1个使用了进程级沙箱。传统上,大家对沙箱的认识大多停留在进程级沙箱,业务进程被运行在一个独立的沙箱进程中,来实现安全隔离保障。但是众多的AI应用没有选择此类沙箱,这是因为:
a.
这类沙箱方案的本质是操作系统级别的虚拟化技术,不信任的代码与可信代码依然共享统一内核,技术原理类似Docker,而Docker已经被证明其弱隔离无法为业务提供足够的安全隔离;
b.
这类方案依赖的namespace/cgroup等技术均需要特权,而目前的业务代码通常都是跑在kubernetes集群的低权限容器中,因此这类沙箱无法不经修改的接入业务。从安全性和易用性上来讲,进程级沙箱在AI 时代已经逐渐退场。
语言级沙箱和系统级沙箱逐渐在AI时代得到青睐。很多AI应用的代码执行任务都不复杂,通过简单的Python脚本或者JavaScript脚本就能够完成,而语言级的沙箱比如Pyodide或者Deno恰好都能满足条件,他们的接入简单,并且从安全性上来讲,有浏览器沙箱的保护,所以也成为一些不太复杂业务的选择。
另一方面,基于gVisor/Firecracker的系统级沙箱也逐渐得到AI应用厂商的青睐,这是因为:
a.
gVisor/Firecracker等是基于轻量级虚拟机的技术,具有强隔离性,与宿主机能够完全隔离开;
b.
系统级的沙箱提供给用户的使用界面为一个完整的Linux操作系统,能够满足更复杂的业务场景。
2) 从对比可以看出,系统级的业务隔离性和业务兼容性都很高,但是他们的接入成本也相对较高。
这是因为gVisor/Firecracker的使用比较复杂,从部署到运行时都容易出问题。所以我们也观察到有一些创业型公司正在这个方向发力,比如e2b和Modal分别把Firecracker和gVisor作为底层代码执行环境提供给用户,让用户能够直接通过SDK的方式使用安全沙箱,大幅降低业务的使用成本。
3) 虽然 gVisor/Firecracker 能够明显提升隔离性,但是作为安全沙箱还需要更精细的安全策略配置。
从上述AI应用的测试结果可以看出,采用了gVisor/Firecracker系统级沙箱,其安全策略依然有很大的提升空间。比如目前的沙箱大部分能够允许任意代码执行,配合外网访问以及对文件系统的写和执行权限,恶意用户能够直接在运行环境中下载后门木马,进行进一步的攻击,一旦被攻击者找到漏洞即能够攻破到基础设施中。
所以使用gVisor/Firecracker等强隔离沙箱只是第一步,一个比较完善的代码执行安全沙箱还应该具有如下安全特性:
01
最小的运行环境:尽量减少系统中非必须组件,比如常见的用于网络探测的 wget、curl、ping 等可执行文件。
02
最小的用户权限:使用非特权用户。
03
严格的安全策略:限制沙箱中能够执行的文件、限制其网络能力与文件读写能力。
04
完善的日志审计:AI 应用在执行 LLM 生成的代码时,需要记录相关日志。这既可以在 AI 应用中完成,也可以在系统级沙箱中完成。
综上,AI应用的代码执行方案选型,对于业务场景比较简单、研发资源有限的公司,可以使用语言级的沙箱,比如Pyodide。对于业务场景比较复杂,研发资源充足并且对安全要求很高的公司可以选择基于gVisor/Firecracker 的系统级安全沙箱。如果需要使用系统级安全沙箱,但是又没有足够的研发运维资源,可以使用商业公司提供的产品化服务。在选择了系统级安全沙箱后,基于纵深防御的原则,还需要为其设计一个具备最小特权运行环境、严格安全策略、完善日志审计的安全配置。
7
总结
安全沙箱是一个古老而现代的话题,说它古老是因为通过安全沙箱执行不可信任的代码始终是计算机系统中的刚需;说它现代是因为随着操作系统与计算机技术的不断发展进化,构建沙箱的技术也在不断发展,从最初的seccomp、ptrace方案,到如今的基于namespace、cgroup等技术的沙箱、基于虚拟化技术的安全容器沙箱、以及基于浏览器实现的各种沙箱,安全沙箱的技术随着计算机系统技术的发展而得到了现代化的进化。
Tong Liu等人在论文中《Demystifying RCE Vulnerabilities in LLM-Integrated Apps》[4] 中总结了AI应用中场景的RCE漏洞。Wiz 在最近的一篇文章[5]中也描述了其通过Python pickle反序列化漏洞攻破Hugging Face的基础设施架构,在其中执行任意代码。这些研究都说明目前AI发展中存在着代码执行相关的安全问题,而沙箱是解决这类安全问题的方式之一。
本文从分析ChatGPT 4的代码执行沙箱为起点,分析了多款AI应用代码执行沙箱的解决方案及安全策略,最后给出了安全沙箱的选型及策略建议,以期业界在LLM如火如荼的发展浪潮中能够重视AI代码执行环境的安全问题,各厂商也能够根据自己的业务需求灵活选择安全可靠的沙箱解决方案。
8
参考文章
[1] gVisor. https://gvisor.dev/
[2] ChatGPT. https://openai.com/gpt-4
[3] e2b. https://e2b.dev/
[4] Liu, Tong, et al. "Demystifying rce vulnerabilities in llm-integrated apps." arXiv preprint arXiv:2309.02926 (2023).
[5] Wiz Security Research. https://www.wiz.io/blog/wiz-and-hugging-face-address-risks-to-ai-infrastructure
![老树开新花:大模型时代的代码执行沙箱 老树开新花:大模型时代的代码执行沙箱](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/07/3-1721905306.png)
原文始发于微信公众号(蚂蚁技术AntTech):老树开新花:大模型时代的代码执行沙箱