llm-sandbox:想给大模型代码运行配置沙箱环境?LLM Sandbox看这一篇就够了!
简介
LLM Sandbox 可连接容器来安全执行代码,本文根据官方文档提炼写了一个工作中可能用到的技术文档说明,包括基本使用,自定义配置,安全策略配置,同时包含部分源码分析等。
llm sandbox基本使用
文档地址:LLM Sandbox Documentation
需要安装docker
启动方式1
with SandboxSession(lang="python",# 语言
backend=SandboxBackend.DOCKER,# 使用docker容器 默认也是这个
verbose=True # 过程日志
) as session:
result = session.run("""
print("Hello from LLM Sandbox!")
print("你好 llm sandbox")
""")
print(result.stdout)
会在项目目录下生成Dockerfile文件和docker-compose.yml文件,生成一个临时镜像,镜像从远程仓库拉取(它自己的python默认镜像),然后运行容器,运行结束后删除容器和镜像。
这里的ghcr.io…就是拉取的临时镜像
此外,会在tmp目录下建一个虚拟环境来运行写入的代码 /tmp/venv (也就是/tmp/venv/bin/python /sandbox/script.py)
工作目录在/sandbox
会把传入的代码复制到这个sandbox目录下
这种方式较慢,毕竟需要拉取镜像,运行容器,删除等一系列操作,不过一切都是临时生成的
启动方式2
也可以自己指定已存在的镜像
with SandboxDockerSession(lang="python",verbose=True,
image="python:3.12", # 使用自定义镜像
) as session:
result = session.run("""
print("Hello from LLM Sandbox!")
print("你好 llm sandbox")
""")
print(result.stdout)
控制台输出:创建工作目录 建虚拟环境 生成py文件并复制到镜像里 运行:/tmp/venv/bin/python /sandbox/d1976f49685a41f1beb60b50979acc4d.py
Using local Docker context since client is not provided.
Using local image python:3.12
Executing command: mkdir -p /sandbox
Executing command: python -m venv --system-site-packages /tmp/venv
Executing command: mkdir -p /tmp/pip_cache
Executing command: /tmp/venv/bin/pip install --upgrade pip --cache-dir /tmp/pip_cache
STDOUT: Requirement already satisfied: pip in /tmp/venv/lib/python3.12/site-packages (25.0.1)
Collecting pip
Downloading pip-25.2-py3-none-any.whl.metadata (4.7 kB)
Downloading pip-25.2-py3-none-any.whl (1.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 1.4 MB/s eta 0:00:00
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 25.0.1
Uninstalling pip-25.0.1:
Successfully uninstalled pip-25.0.1
Successfully installed pip-25.2
Copying C:\Users\linmin\AppData\Local\Temp\tmphobm_nxd.py to /sandbox/d1976f49685a41f1beb60b50979acc4d.py
Executing command: /tmp/venv/bin/python /sandbox/d1976f49685a41f1beb60b50979acc4d.py
STDOUT: Hello from LLM Sandbox!
你好 llm sandbox
Hello from LLM Sandbox!
你好 llm sandbox
Stopped and removed container
会快很多,不需要远程拉取进行,直接用本地的
启动方式3
也可以自己启动好容器直接用
下一个python312镜像
启动:docker start -i my_python_container
注意需要手动添加工作目录/sandbox
并且手动配置虚拟环境/tmp/venv
会自动去找工作目录以及虚拟环境来运行例如之前的:/tmp/venv/bin/python /sandbox/d1976f49685a41f1beb60b50979acc4d.py
可以在虚拟环境里配好需要的包
client = docker.from_env()
# Create and use a sandbox session
with SandboxSession(lang="python",
backend=SandboxBackend.DOCKER,
verbose=True,
container_id="my_python_container",
client=client,
skip_environment_setup=True
) as session:
result = session.run("""
print("Hello from LLM Sandbox!")
print("你好 llm sandbox")
""")
print(result.stdout)
控制台输出:
Connected to existing container my_python_container
Skipping environment setup for existing container
Copying C:\Users\linmin\AppData\Local\Temp\tmp2n67ojhn.py to /sandbox/4d6d9c694352466bb0b0fcd7260d6c95.py
Executing command: /tmp/venv/bin/python /sandbox/4d6d9c694352466bb0b0fcd7260d6c95.py
STDOUT: Hello from LLM Sandbox!
你好 llm sandbox
Hello from LLM Sandbox!
你好 llm sandbox
Disconnected from existing container
预装numpy
client = docker.from_env()
# Create and use a sandbox session
with SandboxSession(lang="python",
backend=SandboxBackend.DOCKER,
verbose=True,
container_id="my_python_container",
client=client,
skip_environment_setup=True
) as session:
result = session.run("""
import numpy as np
# Create an array
arr = np.array([1, 2, 3, 4, 5])
print(f"Array: {arr}")
print(f"Mean: {np.mean(arr)}")
print(f"Sum: {np.sum(arr)}")
""")
print(result.stdout)
控制台输出:
Connected to existing container my_python_container
Skipping environment setup for existing container
Copying C:\Users\linmin\AppData\Local\Temp\tmpz4ez2ks1.py to /sandbox/308f1841870e432983e7c2b1bee99269.py
Executing command: /tmp/venv/bin/python /sandbox/308f1841870e432983e7c2b1bee99269.py
STDOUT: Array: [1 2 3 4 5]
Mean: 3.0
Sum: 15
Array: [1 2 3 4 5]
Mean: 3.0
Sum: 15
Disconnected from existing container
SandboxSession 和 ArtifactSandboxSession 的区别
SandboxSession和ArtifactSandboxSession都是LLM Sandbox库提供的沙箱环境类,用于安全地执行代码,但它们有以下关键区别:
SandboxSession
基础沙箱会话类,用于执行代码并获取标准输出
适用于一般的代码执行需求
主要返回代码执行的标准输出结果
ArtifactSandboxSession
专门用于处理和收集代码执行过程中产生的"产物"(artifacts)
特别适用于生成文件、图像、图表等可视化内容的场景
能够捕获和返回代码执行过程中生成的文件和产物
例子:注意这里的libraries可以在运行之前pip对应的包
def test_container_sandbox_libraries():
client = docker.from_env()
# Create and use a sandbox session
with ArtifactSandboxSession(lang="python",
backend=SandboxBackend.DOCKER,
verbose=True,
container_id="my_python_container",
client=client,
) as session:
result = session.run("""
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('default')
# Generate data
x = np.linspace(0, 10, 100)
y1 = np.sin(x) + np.random.normal(0, 0.1, 100)
y2 = np.cos(x) + np.random.normal(0, 0.1, 100)
# Create plot
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes[0, 0].plot(x, y1, 'b-', alpha=0.7)
axes[0, 0].set_title('Sine Wave')
axes[0, 1].scatter(x[::5], y2[::5], c='red', alpha=0.6)
axes[0, 1].set_title('Cosine Scatter')
axes[1, 0].hist(y1, bins=20, alpha=0.7, color='green')
axes[1, 0].set_title('Sine Distribution')
axes[1, 1].bar(range(10), np.random.rand(10), alpha=0.7)
axes[1, 1].set_title('Random Bar Chart')
plt.tight_layout()
plt.show()
print('Plot generated successfully!')
""",libraries=["matplotlib"])
logger.info(f"Numpy sandbox output:\n{result.stdout}")
for plot in result.plots:
from pathlib import Path
Path("docs/assets").mkdir(parents=True, exist_ok=True)
with Path("docs/assets/example2.png").open("wb") as f:
f.write(base64.b64decode(plot.content_base64))
执行代码的关键函数:session.run方法的参数
在Docker沙箱会话中运行提供的代码。
此方法执行以下步骤:
1. 确保会话已打开(容器正在运行)。
2. 使用特定语言的处理器安装任何指定的`libraries`。
3. 将`code`写入主机上的临时文件。
4. 将此临时文件复制到容器中配置的`workdir`目录。
5. 从语言处理器获取执行命令。
6. 使用`execute_commands`在容器中执行这些命令。
参数:
code (str): 要执行的代码字符串。
libraries (list | None, optional): 在运行代码之前要安装的库列表。
默认为None。
timeout (float | None, optional): 代码执行的超时时间。
默认为None。
返回:
ConsoleOutput: 包含代码执行的stdout、stderr和退出码的对象。
异常:
NotOpenSessionError: 如果会话(容器)当前未打开/运行。
CommandFailedError: 如果任何执行命令失败。
llm sandbox 参数配置
参数:
client (docker.DockerClient | None):要使用的Docker客户端。Docker客户端实例,用于与Docker守护进程通信
image (str | None):要使用的镜像。
dockerfile (str | None):要使用的Dockerfile文件。如果需要从Dockerfile构建镜像,则指定该文件路径
lang (str):要使用的编程语言。
keep_template (bool):是否保留模板镜像。决定是否保留原始模板镜像而不删除
commit_container (bool):是否将容器提交为新镜像。
verbose (bool):是否启用详细输出。
stream (bool):决定输出是流式传输还是批量返回
runtime_configs (dict | None):要使用的运行时配置。
workdir (str):容器内的工作目录路径
security_policy (SecurityPolicy | None):要使用的安全策略。
default_timeout (float | None):要使用的默认超时时间。
execution_timeout (float | None):要使用的执行超时时间。
session_timeout (float | None):要使用的会话超时时间。
container_id (str | None):要连接的现有容器的ID。
skip_environment_setup (bool):是否跳过环境初始化步骤
**kwargs:其他关键字参数。
skip_environment_setup参数的背后
session_base里面有一个方法是environment_setup
-
方法作用:
- 在容器内为特定编程语言配置运行环境
- 在会话初始化阶段自动调用
-
该方法在以下两种情况下会被跳过:
- 当使用现有容器时(通过container_id参数指定)
- 当skip_environment_setup参数设置为True时
另一个方法execute_commands
-
核心功能:
- 按顺序在容器中执行多个命令
- 提供错误处理机制:返回第一个失败命令的输出,或最后一个命令的输出(如果全部成功)
-
参数详解:
- commands参数:
类型:命令列表,支持两种格式:
简单字符串:命令会在默认工作目录中执行
元组形式:(命令字符串, 特定工作目录),允许为每个命令指定不同的工作目录 - workdir参数:
为那些没有指定特定工作目录的命令提供默认工作目录,是可选参数,默认值为None
- commands参数:
-
返回值:
- 返回类型为ConsoleOutput对象 包含最后一个成功执行的命令的输出结果
所以skip_environment_setup参数为false的时候会触发以下命令:
看看PYTHON_CREATE_VENV_COMMAND:
通过session.execute_commands和install安装库
例如:session.execute_command(“pip install requests”)
还可以:session.install([“numpy”, “pandas”, “scikit-learn”])
当然也可以手动去容器里装,例如第一部分的预装numpy
超时配置
三种超时类型:
类型 | 描述 | 默认值 |
---|---|---|
default_timeout |
所有操作的默认超时 | 30 秒 |
execution_timeout |
每次代码运行的超时 | 默认同上 |
session_timeout |
会话最大生命周期 | 无限制 |
可为每次运行单独设置超时
支持重试机制处理 SandboxTimeoutError
后端行为不同:Docker/Podman 会强制终止容器,Kubernetes 监控 Pod 命令执行
例子:
from llm_sandbox import SandboxSession
# Configure timeouts at session creation
with SandboxSession(
lang="python",
default_timeout=30.0, # Default timeout for operations
execution_timeout=60.0, # Timeout for code execution
session_timeout=300.0, # Session expires after 5 minutes
verbose=True
) as session:
# Fast operation - should complete
result = session.run("""
print("Hello, World!")
import time
time.sleep(2)
print("Operation completed")
""")
更细粒度的控制:可以设置单次代码执行的超时时间
例子:
with SandboxSession(lang="python", execution_timeout=10.0) as session:
# 使用默认 10 秒超时
result1 = session.run("print('Normal execution')")
# 为这次运行单独设置 20 秒超时
result2 = session.run("""
import time
time.sleep(15)
print("Long operation completed")
""", timeout=20.0)
# 设置更短的 2 秒超时,可能触发超时异常
try:
session.run("""
import time
time.sleep(5)
print("This might timeout")
""", timeout=2.0)
except SandboxTimeoutError:
print("Operation timed out as expected")
优雅地处理代码执行时发生的超时错误
官方给的自动重试机制的函数:
from llm_sandbox.exceptions import SandboxTimeoutError
def execute_with_retry(session, code, max_retries=3):
"""Execute code with automatic retry on timeout."""
for attempt in range(max_retries):
try:
return session.run(code, timeout=10.0)
except SandboxTimeoutError:
print(f"Attempt {attempt + 1} timed out")
if attempt == max_retries - 1:
raise
print("Retrying...")
说明:
- 每次运行设置 10 秒超时
- 如果发生超时,最多重试 3 次
- 最终仍失败则抛出异常
使用案例:
with SandboxSession(lang="python") as session:
try:
result = execute_with_retry(session, """
import time
import random
time.sleep(random.uniform(5, 15)) # Variable execution time
print("Completed!")
""")
print(result.stdout)
except SandboxTimeoutError:
print("All retry attempts failed")
不同容器的超时处理方式
后端类型 | 超时处理方式 | 资源管理 | 生命周期控制 |
---|---|---|---|
Docker / Podman | 当达到执行超时时间,容器会被强制终止 | 自动清理容器资源 | 容器生命周期由 Sandbox 控制 |
Kubernetes | 超时仅作用于 Pod 内的命令执行阶段,不会终止整个 Pod | Pod 会持续运行,除非手动清理 | Pod 生命周期由 Kubernetes 管理 |
Docker & Podman 行为详解
- 执行超时后,容器会被立即杀掉(kill),防止资源滥用。
- 容器资源(内存、CPU)会被自动释放。
- 适合短生命周期任务或批处理。
创建不同的container时可以配置的运行参数 Runtime Configuration
“Runtime Configuration” 是指在创建沙盒容器时,针对不同后端(Docker、Podman、Kubernetes)所能设置的运行参数。这些配置决定了容器的资源限制、安全性、网络行为、环境变量等,是保障执行安全性和性能的关键部分。
它是通过 runtime_configs
或 pod_manifest
参数传入的配置字典,用于控制容器或 Pod 的运行环境。不同后端支持的配置方式不同:
后端类型 | 配置方式 | 支持内容范围 |
---|---|---|
Docker / Podman | 使用 runtime_configs 参数 |
资源、网络、挂载、安全、环境变量等 |
Kubernetes | 使用 pod_manifest 参数 |
Pod 级别的完整配置,包括资源、安全上下文等 |
Docker / Podman 的配置示例
runtime_configs = {
"memory": "512m", # 限制内存
"cpu_quota": 50000, # 限制 CPU 使用
"network_mode": "bridge", # 网络模式
"volumes": {
"/host/data": {"bind": "/data", "mode": "rw"}
},
"environment": {
"PYTHONPATH": "/app",
"DEBUG": "true"
},
"security_opt": ["no-new-privileges:true"]
}
session = SandboxSession(
image="python:3.9",
backend="docker",
runtime_configs=runtime_configs
)
这些配置通过 Docker SDK 或 Podman SDK 传入,控制容器的创建行为。
支持的配置类型(Docker/Podman)
- 资源限制:如
memory
,cpu_quota
,memswap_limit
- 网络配置:如
network_mode
,dns
,ports
- 挂载卷:如
volumes
映射主机路径 - 环境变量:如
environment
设置运行时变量 - 安全配置:如
privileged
,cap_drop
,security_opt
例子:
- Resource Limits(资源限制)
用于控制容器的内存和 CPU 使用,防止资源滥用:
runtime_configs = {
"memory": "1g", # 限制最大内存为 1GB
"cpu_period": 100000, # CPU 时间周期(微秒)
"cpu_quota": 50000, # CPU 配额(50% 的一个核心)
"memswap_limit": "2g" # 内存 + swap 限制为 2GB
}
- Network Configuration(网络配置)
用于设置容器的网络模式、端口映射和 DNS:
runtime_configs = {
"network_mode": "host", # 使用主机网络
"ports": {
"8080/tcp": 8080 # 映射容器端口到主机
},
"dns": ["8.8.8.8", "8.8.4.4"] # 自定义 DNS 服务器
}
- Volume Mounts(挂载卷)
用于将主机目录挂载到容器中,实现数据共享或配置注入:
runtime_configs = {
"volumes": {
"/host/data": {
"bind": "/data",
"mode": "rw" # 可读写挂载
},
"/host/config": {
"bind": "/config",
"mode": "ro" # 只读挂载
}
}
}
- Environment Variables(环境变量)
runtime_configs = {
"environment": {
"PYTHONPATH": "/app:/libs",
"DEBUG": "true",
"API_KEY": "your-api-key"
}
}
- Security Configuration(安全配置)
用于控制容器的权限、用户身份和能力:
runtime_configs = {
"privileged": False, # 禁用特权模式
"user": "1000:1000", # 指定用户和组运行容器
"cap_drop": ["ALL"], # 移除所有 Linux capabilities
"cap_add": ["NET_ADMIN"], # 添加特定能力
"security_opt": ["no-new-privileges:true"] # 禁止权限提升
}
安全策略配置Security Configuration
通过安全策略(Security Policies)来控制和限制用户代码行为,确保代码执行既安全又可控。
Security Configuration 的核心作用
它允许你在创建沙盒会话时,定义一套安全策略,用于:
- 检测危险代码模式(如系统命令、文件写入)
- 限制导入高风险模块(如
subprocess
) - 设置违规代码的严重性等级(如 HIGH、MEDIUM)
- 阻止或警告潜在的安全风险
入门案例
例子:
from llm_sandbox.security import (
SecurityPolicy,
SecurityPattern,
RestrictedModule,
SecurityIssueSeverity
)
policy = SecurityPolicy(
severity_threshold=SecurityIssueSeverity.MEDIUM,
patterns=[
SecurityPattern(
pattern=r"os\\.system\\s*\\(",
description="System command execution",
severity=SecurityIssueSeverity.HIGH
)
],
restricted_modules=[
RestrictedModule(
name="os",
description="Operating system interface",
severity=SecurityIssueSeverity.HIGH
)
]
)
SecurityPolicy是最大的那个安全策略“容器”,SecurityPattern和RestrictedModule是用来设置具体安全策略的 其中关键参数说明:
参数 | 说明 |
---|---|
severity_threshold |
设置触发阻止的最低严重等级(如 MEDIUM) |
patterns |
自定义正则表达式,用于检测危险代码结构 对应SecurityPattern |
restricted_modules |
限制导入的模块,自动生成语言适配的检测模式 对应RestrictedModule |
上面import里面的第四个模块:用来设置触发等级
SecurityPattern和RestrictedModule区别:
-
SecurityPattern:用于识别如
os.system()
、eval()
、open('w')
等危险操作。 -
RestrictedModule:阻止如
os
、subprocess
、requests
等模块的导入,自动适配语言语法(Python、JavaScript 等)。
例如,限制 os
模块时,系统会自动检测以下导入方式:
import os
from os import system
import os as operating_system
应用场景:
-
在创建
SandboxSession
时传入策略对象,实现代码执行前的安全检查。 -
可结合
is_safe()
方法判断代码是否合规,并返回违规详情。
with SandboxSession(lang="python", security_policy=policy) as session:
is_safe, violations = session.is_safe(code)
if is_safe:
result = session.run(code)
else:
for v in violations:
print(f"- {v.description} (Severity: {v.severity.name})")
安全等级Severity Levels
安全策略中的每个违规项(如危险代码模式或被限制的模块)都被赋予一个严重性等级,用于衡量其潜在风险。系统会根据你设定的阈值(severity_threshold
)来决定是否允许该代码执行。
四个严重性等级详解
等级 | 值 | 描述 | 典型用途 |
---|---|---|---|
SAFE |
0 | 无安全问题 | 允许所有代码,适用于完全信任环境 |
LOW |
1 | 轻微风险 | 适用于开发环境,允许调试性代码 |
MEDIUM |
2 | 中等风险 | 适用于生产环境,有一定控制要求 |
HIGH |
3 | 高风险 | 严格限制,适用于安全敏感场景 |
阈值行为说明
当你设置:
severity_threshold = SecurityIssueSeverity.MEDIUM
系统将:
- ✅ 允许
SAFE
和LOW
等级的代码 - ❌ 阻止
MEDIUM
和HIGH
等级的违规项
这意味着你可以灵活控制系统的容忍度。例如,在开发环境中你可能允许 eval()
,但在生产环境中必须阻止它。
应用示例
python
policy = SecurityPolicy(
severity_threshold=SecurityIssueSeverity.MEDIUM,
patterns=[
SecurityPattern(
pattern=r"eval\s*\(",
description="Dynamic code evaluation",
severity=SecurityIssueSeverity.MEDIUM
),
SecurityPattern(
pattern=r"os\.system\s*\(",
description="System command execution",
severity=SecurityIssueSeverity.HIGH
)
]
)
在这个策略中:
- 如果代码包含
eval()
→ 被阻止(因为是 MEDIUM) - 如果包含
os.system()
→ 被阻止(因为是 HIGH) - 如果只是普通打印语句 → 被允许(因为是 SAFE)
Security Patterns
Security Pattern 是一种基于正则表达式的检测规则,用于识别代码中可能存在的高风险操作,比如系统命令执行、动态代码调用、文件写入、网络连接等。
每个模式都包含以下信息:
pattern
:用于匹配危险代码结构的正则表达式description
:对该模式的简要说明severity
:该行为的严重性等级(SAFE、LOW、MEDIUM、HIGH)
典型示例
以下是文档中列出的几个关键安全模式:
SecurityPattern(
pattern=r"\bos\.system\s*\(",
description="System command execution", #os.system() 系统命令执行
severity=SecurityIssueSeverity.HIGH #匹配 Python 中调用 os.system() 的语句,例如:os.system("rm -rf /")
)
SecurityPattern(
pattern=r"\beval\s*\(",
description="Dynamic code evaluation", #eval() 动态代码求值 匹配使用 eval() 的语句,例如:eval("2 + 2")
severity=SecurityIssueSeverity.MEDIUM #可执行任意字符串形式的代码,容易被注入恶意内容
)
SecurityPattern(
pattern=r"\bopen\s*\([^)]*[' \"][wa][' \"][^)]*\)", #open(..., 'w'/'a') 文件写入操作
description="File write operations", #匹配打开文件用于写入或追加的语句,例如:
severity=SecurityIssueSeverity.MEDIUM #open("data.txt", "w") open("log.txt", "a")
)
SecurityPattern(
pattern=r"\bsocket\.socket\s*\(", #socket.socket() 原始网络连接
description="Raw socket creation", #匹配创建原始 socket 的语句,例如: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 风险说明:可用于建立任意网络连接,绕过平台网络控制。潜在用于数据泄露、远程控制或攻击行为。
severity=SecurityIssueSeverity.MEDIUM
)
这些模式会在代码执行前进行匹配分析,若发现违规行为且其严重性高于设定阈值,则会阻止执行。
应用方式
这些模式通常作为 SecurityPolicy
的一部分传入:
policy = SecurityPolicy(
severity_threshold=SecurityIssueSeverity.MEDIUM,
patterns=[...], # 包含多个 SecurityPattern
restricted_modules=[...] # 可配合模块限制使用
)
也可以动态添加模式:
policy.add_pattern(SecurityPattern(...))
Restricted Modules
“Restricted Modules” 是用于限制用户代码中导入某些高风险模块的机制。这一部分是安全策略的核心组成之一,能有效防止用户访问系统级资源、执行外部命令或进行网络通信。
它是通过 RestrictedModule
对象定义的模块限制规则,系统会在代码执行前自动检测是否导入了这些模块,并根据其严重性等级决定是否阻止执行。
典型示例
RestrictedModule(name="os", description="Operating system interface", severity=SecurityIssueSeverity.HIGH)
RestrictedModule(name="subprocess", description="Process execution", severity=SecurityIssueSeverity.HIGH)
RestrictedModule(name="socket", description="Network operations", severity=SecurityIssueSeverity.MEDIUM)
RestrictedModule(name="requests", description="HTTP library", severity=SecurityIssueSeverity.MEDIUM)
这些模块分别代表:
os
:访问操作系统接口,如文件系统、环境变量subprocess
:执行外部命令,风险极高socket
:创建原始网络连接requests
:发起 HTTP 请求,可能访问敏感资源
应用方式
policy = SecurityPolicy(
severity_threshold=SecurityIssueSeverity.MEDIUM,
restricted_modules=[
RestrictedModule(name="os", description="Operating system interface", severity=SecurityIssueSeverity.HIGH),
RestrictedModule(name="subprocess", description="Process execution", severity=SecurityIssueSeverity.HIGH)
]
)
在执行代码前,使用 session.is_safe(code)
方法进行安全检查,若检测到受限模块且严重性高于阈值,则阻止执行。同上一部分
python的综合安全策略案例
# Python-specific dangerous patterns
python_patterns = [
# Dynamic imports
SecurityPattern(r"\b__import__\s*\(", "Dynamic imports", SecurityIssueSeverity.MEDIUM),
# Attribute manipulation
SecurityPattern(r"\b(getattr|setattr|delattr)\s*\(", "Dynamic attributes", SecurityIssueSeverity.LOW),
# Pickle operations (deserialization risk)
SecurityPattern(r"\bpickle\.(loads?|load)\s*\(", "Pickle deserialization", SecurityIssueSeverity.MEDIUM),
# Code execution
SecurityPattern(r"\b(eval|exec|compile)\s*\(", "Code execution", SecurityIssueSeverity.HIGH)
]
# Python-specific restricted modules
python_modules = [
RestrictedModule("os", "Operating system interface", SecurityIssueSeverity.HIGH),
RestrictedModule("subprocess", "Process execution", SecurityIssueSeverity.HIGH),
RestrictedModule("ctypes", "Foreign function library", SecurityIssueSeverity.HIGH),
RestrictedModule("importlib", "Dynamic imports", SecurityIssueSeverity.MEDIUM)
]
Advanced Pattern Examples
基础安全模式的补充,专门用于识别更复杂或更隐蔽的高风险代码行为,例如:
- 网络连接与外部 API 调用
- 文件系统的写入、删除、移动操作
- 云 SDK 的使用(如 boto3、google.cloud)
- 机器学习框架或加密库的调用
这些模式通过正则表达式定义,并赋予不同的严重性等级,作为 SecurityPolicy
的一部分应用于代码执行前的安全审查。
网络安全模式(Network Security Patterns)
network_patterns = [
SecurityPattern(r"\bsocket\.socket\s*\(", "Raw socket creation", MEDIUM),
SecurityPattern(r"\b\w+\.connect\s*\(", "Network connections", MEDIUM),
SecurityPattern(r"requests\.(get|post|put|delete)\s*\(", "HTTP requests", LOW)
]
检测目标:
- 创建 socket → 潜在绕过网络限制
- 使用
.connect()
→ 建立外部连接 - 使用
requests
发起 HTTP 请求 → 可能访问敏感资源
文件系统安全模式(File System Security Patterns)
file_patterns = [
SecurityPattern(r"\bopen\s*\([^)]*[' \"][wa][' \"][^)]*\)", "File write operations", MEDIUM),
SecurityPattern(r"\bos\.(remove|unlink|rmdir)\s*\(", "File deletion operations", HIGH),
SecurityPattern(r"\bshutil\.(rmtree|move|copy)\s*\(", "File system manipulation", MEDIUM)
]
检测目标:
- 写入文件 → 可能篡改数据
- 删除文件 → 高风险破坏行为
- 移动/复制文件 → 数据泄露或覆盖
云服务与框架调用(来自 Custom Policy 示例)
SecurityPattern(r"\b(boto3|google\.cloud|azure)\b", "Cloud SDK usage", HIGH)
SecurityPattern(r"requests\.(get|post)\s*\([' \"]?.*internal\.company\.com", "Internal network access", HIGH)
SecurityPattern(r"\b(tensorflow|torch|keras)\b", "ML framework usage", LOW)
检测目标:
- 使用云 SDK → 可能访问云资源或凭证
- 访问公司内网域名 → 数据泄露风险
- 使用机器学习框架 → 高资源消耗或模型注入风险
应用方式
这些高级模式可以通过 SecurityPolicy
的 add_pattern()
方法动态添加,也可以在策略初始化时一次性传入:
policy = SecurityPolicy(
severity_threshold=SecurityIssueSeverity.MEDIUM,
patterns=network_patterns + file_patterns
)
系统会在执行前自动分析代码,若发现匹配项且严重性高于阈值,则阻止执行并返回违规详情。
连接远程的Docker daemon
import docker
# Connect to remote Docker daemon
client = docker.DockerClient(
base_url='tcp://docker-host:2375',
version='auto',
timeout=30
)
with SandboxSession(
backend=SandboxBackend.DOCKER,
client=client,
lang="python"
) as session:
pass
# Use Docker context
client = docker.DockerClient.from_env()
container commit
# Save container state after execution
with SandboxSession( #with 块退出时,触发 session.close() 逻辑。
backend=SandboxBackend.DOCKER,
lang="python",
commit_container=True, # 会话结束时自动提交容器状态为新镜像。
image="my-base-image:latest" #基于此镜像启动容器(若本地不存在会自动拉取)。
) as session:
# Install packages and setup environment
session.install(["numpy", "pandas", "scikit-learn"])
session.run("echo 'Environment configured'")
#将临时容器的可写层合并为新镜像层,标签为 my-base-image:latest
# 后续使用保存的镜像
with SandboxSession(image="my-base-image:latest") as new_session:
new_session.run("python -c 'import numpy; print(numpy.__version__)'")
支持的语言
支持的语言概览
语言 | 版本 | 包管理器 | 支持绘图 | 默认镜像 |
---|---|---|---|---|
Python | 3.11 | pip | ✅ | ghcr.io/vndee/sandbox-python-311-bullseye |
R | 4.5.1 | CRAN | ✅ | ghcr.io/vndee/sandbox-r-451-bullseye |
JavaScript | Node 22 | npm | ❌ | ghcr.io/vndee/sandbox-node-22-bullseye |
Java | 11 | Maven | ❌ | ghcr.io/vndee/sandbox-java-11-bullseye |
C++ | GCC 11.2 | apt | ❌ | ghcr.io/vndee/sandbox-cpp-11-bullseye |
Go | 1.23.4 | go get | ❌ | ghcr.io/vndee/sandbox-go-123-bullseye |
Python 特性详解
- 功能最丰富:支持包管理、绘图提取、数据科学工作流。
- 包安装方式:
- 执行时自动安装:
libraries=["numpy", "pandas"]
- 单独安装:
session.install(["scikit-learn"])
- 执行时自动安装:
- 绘图提取:支持 matplotlib、seaborn、plotly,自动提取图像。
- 数据科学支持:内置虚拟环境,支持 sklearn、pandas、numpy 等。
- 自定义镜像:可使用 slim 镜像、Jupyter 镜像或自定义 Dockerfile。
更多推荐
所有评论(0)