ASP.NET Core中如何实现进程沙箱以限制用户提交C#代码的权限?
.NET Core 在线C#代码运行沙箱限制方案
代码层API访问管控
由于.NET Core 不支持AppDomain与CAS机制,需要从编译、执行两个阶段做主动拦截:
- 编译期白名单校验
基于Roslyn编译器API对用户提交的代码做语法树分析:- 遍历所有语法节点,仅允许白名单内的命名空间、类型被调用,直接拦截
System.IO、System.Diagnostics等危险命名空间的引用,粒度可细化到具体类与方法,避免用户调用进程启动、文件读写相关的API - 自定义编译时的程序集引用列表,仅引入你允许的安全程序集(如
System.Runtime、System.Linq等),完全移除System.IO.FileSystem、System.Diagnostics.Process等程序集的引用,用户代码调用未引用程序集的API会直接编译失败 - 额外禁止
System.Reflection、System.Reflection.Emit等所有反射、动态代码生成相关的API,防止用户通过反射绕过直接引用限制
- 遍历所有语法节点,仅允许白名单内的命名空间、类型被调用,直接拦截
- 执行期隔离
使用.NET Core 提供的AssemblyLoadContext(ALC)加载用户编译后的程序集:- 每个用户代码对应一个独立的ALC,禁止该ALC加载非白名单的程序集
- 给用户代码执行设置严格的超时时间,超时后直接卸载整个ALC终止执行,避免长时间占用资源
容器层权限收窄
作为第二道防护,即使代码层限制被绕过,容器层也能拦截恶意操作:
- 硬资源限制
给每个单次代码执行的容器配置严格的资源上限:CPU限制为0.1核及以下,内存限制为256M及以下,磁盘配额限制为100M及以下,进程数上限设置为2,从资源层面杜绝挖矿程序正常运行、大文件占满存储的风险 - 最小权限运行
- 容器使用非root用户启动,关闭所有不需要的Linux Capabilities,禁止特权模式运行,用户即使调用
shutdown、进程启动相关命令也没有执行权限 - 将容器根文件系统设为只读,仅开放一个小容量的临时可写目录,禁止容器内部访问公网与宿主机网络,避免用户下载恶意程序、发起网络攻击
- 容器使用非root用户启动,关闭所有不需要的Linux Capabilities,禁止特权模式运行,用户即使调用
- 生命周期管控
单次代码执行请求对应一个全新的临时容器,代码执行完成后立刻销毁容器,不做复用。设置容器最长存活时间为30秒,超时直接强制销毁,从根本上杜绝长时间运行的恶意进程。
内容的提问来源于stack exchange,提问作者Georgi Yankov
相关产品推荐
相关产品推荐

