速率限制、沙箱化與執行控制
進階5 分鐘閱讀更新於 2026-03-13
AI API 的速率限制策略、以 E2B 與 Docker 進行程式碼執行沙箱化、工具呼叫核准工作流,以及 AI 代理的最小權限原則。
架構層級控制是攻擊者最難繞過的防禦,因為它們在模型影響範圍之外運作。越獄後的模型即使想執行惡意程式碼,若執行被沙箱化便做不到;被誘騙去呼叫危險工具的代理,若這些工具需要人類核准,也無法執行。
速率限制策略
AI API 的速率限制不同於傳統 Web API,因為 AI 請求的成本(運算與財務)變化極大。
速率限制的維度
| 維度 | 限制對象 | 為何重要 |
|---|---|---|
| 每分鐘請求數 | 原始請求計數 | 阻止自動化攻擊工具 |
| 每分鐘符元數 | 輸入 + 輸出符元總數 | 防止成本濫用與上下文塞填 |
| 並行請求數 | 同時在途請求 | 防止資源耗盡 |
| 每小時成本 | 推論的金錢成本 | 防止利用造成之財務損害 |
| 每會話請求數 | 對話內訊息數 | 防止多輪升級 |
實作模式
from dataclasses import dataclass, field
from datetime import datetime, timedelta
@dataclass
class RateLimitConfig:
requests_per_minute: int = 20
tokens_per_minute: int = 40_000
max_input_tokens: int = 4_096
max_output_tokens: int = 4_096
max_session_messages: int = 50
cost_limit_per_hour_usd: float = 10.0
class AIRateLimiter:
def __init__(self, config: RateLimitConfig):
self.config = config
self.windows: dict[str, list] = {}
def check_and_record(
self, user_id: str, input_tokens: int, session_messages: int
) -> tuple[bool, str]:
now = datetime.utcnow()
window_start = now - timedelta(minutes=1)
key = f"rpm:{user_id}"
# Request rate check
recent = [t for t in self.windows.get(key, []) if t > window_start]
if len(recent) >= self.config.requests_per_minute:
return False, "Rate limit exceeded: too many requests"
# Input size check
if input_tokens > self.config.max_input_tokens:
return False, f"Input too large: {input_tokens} tokens"
# Session length check
if session_messages > self.config.max_session_messages:
return False, "Session message limit reached"
recent.append(now)
self.windows[key] = recent
return True, "OK"紅隊對速率限制的繞過技術
| 技術 | 說明 | 緩解 |
|---|---|---|
| 分散請求 | 使用多個 API 金鑰或帳號 | 按組織聚合之限制 |
| 慢而穩 | 剛好保持在速率限制之下 | 以更長視窗做行為分析 |
| 會話輪替 | 開新會話以重設會話限制 | 以使用者 (非會話) 為單位追蹤 |
| 離峰時段 | 在流量低時段發動攻擊,動態限制較高 | 不論負載皆採固定速率限制 |
程式碼執行沙箱化
當 AI 代理產生並執行程式碼時,沙箱化至關重要。沒有沙箱化,被入侵的代理可存取主機檔案系統、網路,以及其他基礎設施。
E2B 提供專為 AI 程式碼執行設計的雲端沙箱環境:
from e2b_code_interpreter import Sandbox
# Create isolated sandbox with 30-second timeout
sandbox = Sandbox(timeout=30)
# Execute AI-generated code in isolation
result = sandbox.run_code("""
import os
# This runs in a completely isolated environment
# No access to host filesystem, network restrictions applied
print(os.listdir('/')) # Only sees sandbox filesystem
""")
print(result.text) # Output from sandboxed execution
sandbox.kill() # Clean up安全屬性:
- 隔離的檔案系統 (無主機存取)
- 網路限制 (可設定允許清單)
- CPU/記憶體上限
- 自動逾時與清理
- 多次執行間不持久化
Docker 容器為程式碼執行提供行程層級的隔離:
import docker
import tempfile
client = docker.from_env()
def execute_sandboxed(code: str, timeout: int = 10) -> str:
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
f.write(code)
f.flush()
container = client.containers.run(
"python:3.11-slim",
command=f"python /code/{f.name.split('/')[-1]}",
volumes={f.name: {"bind": f"/code/{f.name.split('/')[-1]}", "mode": "ro"}},
network_disabled=True, # No network access
mem_limit="256m", # Memory cap
cpu_period=100000, # CPU throttling
cpu_quota=50000,
read_only=True, # Read-only filesystem
remove=True, # Auto-cleanup
timeout=timeout,
)
return container.decode("utf-8")AI 沙箱化的關鍵 Docker 旗標:
network_disabled=True—— 防止資料外洩read_only=True—— 防止檔案系統修改mem_limit—— 防止記憶體耗盡攻擊--security-opt=no-new-privileges—— 防止權限提升
WASM 執行環境為輕量程式碼執行提供最強隔離:
# Using wasmtime for sandboxed Python execution
# Pyodide runs Python in a WASM sandbox with no system access
from pyodide_sandbox import PySandbox
sandbox = PySandbox(
allowed_imports=["math", "json", "re"], # Whitelist imports
max_execution_time_ms=5000,
max_memory_mb=64,
)
result = sandbox.execute(ai_generated_code)取捨: 隔離最強,但能力最受限。無檔案系統、無網路、標準函式庫受限。
工具呼叫核准工作流
對能執行真實世界動作的 AI 代理 (發送電子郵件、修改資料庫、進行採購),核准關卡可防止未授權動作。
核准架構
from enum import Enum
class ApprovalPolicy(Enum):
AUTO_APPROVE = "auto" # Low-risk tools
NOTIFY_AND_PROCEED = "notify" # Medium-risk: log but allow
REQUIRE_APPROVAL = "approve" # High-risk: block until human approves
ALWAYS_DENY = "deny" # Forbidden tools
TOOL_POLICIES = {
"search_web": ApprovalPolicy.AUTO_APPROVE,
"read_file": ApprovalPolicy.NOTIFY_AND_PROCEED,
"send_email": ApprovalPolicy.REQUIRE_APPROVAL,
"execute_sql": ApprovalPolicy.REQUIRE_APPROVAL,
"delete_record": ApprovalPolicy.ALWAYS_DENY,
"modify_permissions": ApprovalPolicy.ALWAYS_DENY,
}
class ToolGatekeeper:
def __init__(self, policies: dict[str, ApprovalPolicy]):
self.policies = policies
async def check_tool_call(
self, tool_name: str, arguments: dict, user_id: str
) -> tuple[bool, str]:
policy = self.policies.get(tool_name, ApprovalPolicy.ALWAYS_DENY)
if policy == ApprovalPolicy.AUTO_APPROVE:
return True, "Auto-approved"
elif policy == ApprovalPolicy.NOTIFY_AND_PROCEED:
await self.log_notification(tool_name, arguments, user_id)
return True, "Approved with notification"
elif policy == ApprovalPolicy.REQUIRE_APPROVAL:
approved = await self.request_human_approval(
tool_name, arguments, user_id
)
return approved, "Human review"
else:
return False, f"Tool '{tool_name}' is forbidden"紅隊考量
| 攻擊 | 核准控制 | 繞過可能性 |
|---|---|---|
| 對禁用工具的直接呼叫 | ALWAYS_DENY | 無 —— 於架構層被阻擋 |
| 允許工具的引數注入 | 工具為 AUTO_APPROVE | 高 —— 引數未被審查 |
| 工具串接 (安全工具串成不安全結果) | 個別工具政策 | 中 —— 串接造成湧現風險 |
| 核准疲乏 (大量低風險請求) | REQUIRE_APPROVAL | 中 —— 多次核准後人類會機械式按過 |
AI 代理的最小權限原則
最小權限是代理式 AI 系統最重要的架構防禦。
實作檢查清單
| 原則 | 實作 | 範例 |
|---|---|---|
| 最小工具集 | 只註冊代理實際需要的工具 | 客服機器人僅取得 search_faq 與 create_ticket,不取得 execute_sql |
| 先讀後寫 | 預設僅讀取;寫入需明確授權 | 代理可讀取資料庫,但在無升級會話下不可修改 |
| 範圍受限的憑證 | 每個工具取得僅限於其功能的憑證 | 電子郵件工具僅能自特定地址發送至允許網域 |
| 時效性存取 | 權限於一定會話或時間窗後過期 | 資料庫寫入存取於 5 分鐘後撤銷 |
| 稽核軌跡 | 記錄每次工具呼叫之完整引數 | 可搜尋之所有代理動作日誌,供鑑識審查 |
延伸閱讀
- LLM 應用的縱深防禦 —— 執行控制在防禦堆疊中的位置
- 執行時監控與異常偵測 —— 偵測繞過嘗試
- 護欄與安全層架構 —— 互補的護欄層
- 工具濫用 —— 本文控制所防禦之攻擊
相關主題
- LLM 應用的縱深防禦 —— 執行控制於防禦堆疊中的位置
- 執行時監控與異常偵測 —— 偵測對執行控制的繞過嘗試
- 代理架構與工具使用模式 —— 本文控制所防禦之代理模式
- 護欄與安全層架構 —— 互補的護欄層
參考資料
- "E2B Documentation: AI Code Execution Sandbox" - E2B (2025) —— 為 AI 代理設計之雲端沙箱執行環境文件
- "Docker Security Best Practices" - Docker Inc. (2025) —— 官方容器隔離安全指引,涵蓋停用網路與唯讀檔案系統
- "Principle of Least Privilege in Modern Applications" - NIST SP 800-53 (2023) —— 定義適用於 AI 代理工具存取之最小權限要求的聯邦安全控制
- "OWASP Top 10 for LLM Applications: LLM08 Excessive Agency" - OWASP (2025) —— 本文執行控制所緩解之過度權限 AI 代理的風險分類
Knowledge Check
一個 AI 代理已被越獄,攻擊者指示它刪除資料庫中所有紀錄。該代理擁有 'execute_sql' 工具 (REQUIRE_APPROVAL 政策) 與 'delete_record' 工具 (ALWAYS_DENY 政策)。會發生什麼?