🛡️ 构建 Agent 实践指南 — 安全机制

沙箱 · 审批 · 注入防护 · Failover — 从 20 个 Agent 项目源码提炼的安全方法论

目录

  1. 1. 威胁模型:Agent 面临的 5 类安全风险
  2. 2. 沙箱隔离:从 chroot 到 Docker 到 Seatbelt
  3. 3. 审批系统:三级权限与 LLM Guardian
  4. 4. 注入防护:静态扫描 vs LLM 审查 vs 运行时网关
  5. 5. 工具策略:Allow/Deny/Policy 三层管控
  6. 6. 安全审计:配置扫描与合规检查
  7. 7. 运行时防护:ReDoS、凭证泄露、卡死检测
  8. 8. 对比矩阵
  9. 9. 模式提炼与最佳实践

1. 威胁模型:Agent 面临的 5 类安全风险

在分析 20 个 Agent 项目后,我们识别出 Agent 系统面临的 5 大类安全威胁:

Agent 安全威胁模型 ┌─────────────────────────────────────────────────────────────────┐ │ 外部攻击面 │ │ ┌──────────────┐ ┌──────────────┐ ┌─────────────────────┐ │ │ │ ① Prompt 注入 │ │ ② 数据渗出 │ │ ③ 供应链攻击 │ │ │ │ 恶意指令伪装 │ │ 凭证/密钥外泄 │ │ 恶意 Skill/Plugin │ │ │ └──────────────┘ └──────────────┘ └─────────────────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ 内部风险面 │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ ④ 权限滥用 │ │ ⑤ 破坏性操作 │ │ │ │ Agent 越权执行│ │ rm -rf / 覆盖│ │ │ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────┘

① Prompt 注入 Hermes Agent Zero

攻击者通过用户输入、网页内容、文件内容向 Agent 注入恶意指令。这是 Agent 最独特的威胁——因为 Agent 会执行它读到的内容。

② 数据渗出 Hermes OpenClaw

Agent 被诱导将敏感信息(API Key、SSH 密钥、.env 文件)发送到外部服务器。

③ 供应链攻击 Hermes OpenClaw

从注册表安装的第三方 Skill/Plugin 可能包含恶意代码,在 Agent 上下文中执行任意操作。

④ 权限滥用 Codex CLI OpenClaw

Agent 在未获授权的情况下访问或修改超出其职责范围的文件、服务或系统资源。

⑤ 破坏性操作 Codex CLI Smolagents

Agent 执行不可逆的破坏性命令,如 rm -rf /mkfsdd of=/dev/sda 等。

2. 沙箱隔离:从 chroot 到 Docker 到 Seatbelt

沙箱是 Agent 安全的物理隔离层——即使 Agent 被完全控制,也无法突破沙箱影响宿主系统。

2.1 OpenClaw Docker 沙箱 OpenClaw

OpenClaw 实现了最完善的 Docker 沙箱系统,包含 30+ 安全配置项

OpenClaw 沙箱安全架构 ┌─────────────── Host ───────────────┐ │ OpenClaw Gateway │ │ ┌─────────────────────────────┐ │ │ │ Sandbox Config │ │ │ │ • image: bookworm-slim │ │ │ │ • readOnlyRoot: true │ │ │ │ • network: none │ │ │ │ • capDrop: ALL │ │ │ │ • seccompProfile │ │ │ │ • pidsLimit / memory / cpus │ │ │ └──────────┬──────────────────┘ │ │ │ create │ │ ┌──────────▼──────────────────┐ │ │ │ Docker Container │ │ │ │ /workspace (rw, agent 作业) │ │ │ │ /agent (ro, workspace 只读) │ │ │ │ ❌ /etc, /proc, /sys, /root │ │ │ │ ❌ ~/.ssh, ~/.aws, ~/.gnupg│ │ │ │ ❌ /var/run/docker.sock │ │ │ └─────────────────────────────┘ │ └────────────────────────────────────┘

核心安全验证代码——validate-sandbox-security.ts 在创建容器前检查:

// BLOCKED_HOST_PATHS: 永远不应暴露到沙箱内的宿主路径
const BLOCKED_HOST_PATHS = [
  "/etc", "/proc", "/sys", "/dev", "/root", "/boot",
  "/run", "/var/run", "/var/run/docker.sock",
];

// BLOCKED_HOME_SUBPATHS: 用户目录下的敏感子目录
const BLOCKED_HOME_SUBPATHS = [
  ".aws", ".cargo", ".config", ".docker",
  ".gnupg", ".netrc", ".npm", ".ssh",
];

// BLOCKED_SECCOMP/BLOCKED_APPARMOR: 禁止 "unconfined"
const BLOCKED_SECCOMP_PROFILES = new Set(["unconfined"]);
const BLOCKED_APPARMOR_PROFILES = new Set(["unconfined"]);

Docker 配置类型 SandboxDockerSettings 暴露了丰富的安全控制:

export type SandboxDockerSettings = {
  image?: string;              // 沙箱镜像
  readOnlyRoot?: boolean;      // 只读根文件系统
  network?: string;            // 网络模式: bridge|none|custom
  capDrop?: string[];          // 丢弃 Linux capabilities
  seccompProfile?: string;     // Seccomp 配置文件
  apparmorProfile?: string;    // AppArmor 配置
  pidsLimit?: number;          // PID 限制
  memory?: string | number;    // 内存限制
  cpus?: number;               // CPU 限制
  ulimits?: Record<string, ...>;  // Ulimit 设置
  dns?: string[];              // DNS 服务器
  extraHosts?: string[];       // 额外主机映射
  binds?: string[];            // 额外绑定挂载
  dangerouslyAllow*?: boolean; // 危险覆盖(需显式启用)
};
OpenClaw 的沙箱设计遵循「默认拒绝,显式允许」原则:dangerouslyAllow* 前缀的选项需要显式启用,命名本身就发出警告。

2.2 Codex CLI 多平台沙箱 Codex CLI

Codex CLI (OpenAI) 实现了跨平台沙箱——macOS 用 Seatbelt、Linux 用 Docker、Windows 用独立沙箱:

// codex-rs/core/src/sandboxing/mod.rs
pub struct ExecRequest {
    pub sandbox: SandboxType,           // 沙箱类型
    pub permission_profile: PermissionProfile,  // 权限配置
    pub file_system_sandbox_policy: FileSystemSandboxPolicy,  // 文件系统策略
    pub network_sandbox_policy: NetworkSandboxPolicy,  // 网络策略
    pub windows_sandbox_level: WindowsSandboxLevel,   // Windows 沙箱级别
    pub windows_sandbox_private_desktop: bool,        // 私有桌面隔离
}

三级权限配置(Permission Profile):

// 内置权限配置文件
BUILT_IN_PERMISSION_PROFILE_READ_ONLY    // 只读:仅允许读工作区文件
BUILT_IN_PERMISSION_PROFILE_WORKSPACE    // 工作区:允许读写工作区,禁止访问外部
BUILT_IN_PERMISSION_PROFILE_DANGER_FULL_ACCESS  // 完全访问:危险,需显式选择

文件系统沙箱策略精细控制每个路径的访问模式:

pub enum FileSystemAccessMode {
    None,       // 完全禁止
    ReadOnly,   // 只读
    ReadWrite,  // 读写
}

pub struct FileSystemSandboxEntry {
    pub path: AbsolutePathBuf,
    pub mode: FileSystemAccessMode,
}

2.3 OpenHands Docker 沙箱 OpenHands

OpenHands 使用 Docker 容器作为 Agent 的执行环境,通过 DockerSandboxService 管理:

# 容器创建时的安全设置
- 非特权用户运行
- 资源限制(CPU/内存)
- 网络隔离选项
- 会话认证密钥注入
- Webhook 回调变量隔离

OpenHands 支持 3 种沙箱模式:

2.4 Smolagents Python 沙箱 Smolagents

Smolagents 采取了完全不同的沙箱策略——在 Python 解释器级别实现安全控制:

# local_python_executor.py — 受限的 Python 执行环境
class LocalPythonExecutor(PythonExecutor):
    """This executor evaluates Python code with restricted access to
    imports and built-in functions."""

# 安全装饰器:检查返回值
@safer_eval  # 检查评估函数的返回值
@safer_func  # 检查普通函数的返回值

# 禁止访问的危险函数
def check_safer_result(result, static_tools, authorized_imports):
    # 验证返回的对象不来自禁止的模块
    if result.__module__ == module_name:
        raise InterpreterError(f"Forbidden access to function: {function_name}")
沙箱选型决策树:

3. 审批系统:三级权限与 LLM Guardian

审批系统解决的核心问题:Agent 想要执行危险操作时,谁来决定是否允许?

3.1 OpenClaw 多层审批 OpenClaw

OpenClaw 的审批系统覆盖 exec、插件、会话操作等多个维度:

OpenClaw 审批流程 Agent 请求执行命令 │ ▼ ┌─────────────────┐ │ ExecSecurity 级别 │ ← 配置层:deny / allowlist / full └────────┬────────┘ │ ┌────▼────┐ │ deny? │──── 是 ──→ ❌ 直接拒绝 └────┬────┘ │ 否 ┌────▼────────┐ │ allowlist? │ └────┬────────┘ │ ┌────▼──────────┐ │ 匹配允许列表? │ └──┬─────────┬──┘ 是 │ │ 否 ▼ ▼ ✅ 执行 ┌──────────────┐ │ ExecAsk 模式 │ ← on-miss / always └──────┬───────┘ │ ┌─────────▼──────────┐ │ 发送审批请求给用户 │ │ (Telegram/Discord) │ └─────────┬──────────┘ │ ┌─────────▼──────────┐ │ 用户 /approve 或拒绝 │ └─────────┬──────────┘ │ ✅ 或 ❌

核心类型定义:

// exec-approvals.ts
export type ExecSecurity = "deny" | "allowlist" | "full";
export type ExecAsk = "off" | "on-miss" | "always";
export type ExecHost = "sandbox" | "gateway" | "node";

// 审批请求
export type ExecApprovalRequest = {
  command: string;
  host: ExecHost;
  security: ExecSecurity;
  ask: ExecAsk;
  // ... 更多上下文字段
};

// 审批决策
export type ExecApprovalDecision = "allow" | "deny" | "allow-always";

审批请求通过平台原生能力发送(Telegram inline buttons、Discord reactions),确保用户体验无缝。

3.2 Codex CLI Guardian —— LLM 驱动的自动审批 Codex CLI

Codex CLI 的 Guardian 是最创新的安全机制——用另一个 LLM 会话来审查 Agent 的操作请求

Codex Guardian 审查流程 Agent 请求执行命令(如 rm -rf node_modules) │ ▼ ┌────────────────────────────────────────────────┐ │ Guardian Review Session │ │ │ │ 1. 重建紧凑的对话摘要(保留用户意图+近期上下文) │ │ 2. 将请求的操作格式化为结构化 JSON │ │ 3. 独立 LLM 会话评估风险级别 │ │ 4. 返回结构化评估结果 │ │ │ │ ┌──────────────────────────────────┐ │ │ │ GuardianAssessment │ │ │ │ risk_level: low/medium/high │ │ │ │ user_authorization: granted/... │ │ │ │ outcome: allow/deny │ │ │ │ rationale: "..." │ │ │ └──────────────────────────────────┘ │ │ │ │ Timeout: 90s (Fail Closed) │ │ Max Consecutive Denials: 3 (Circuit Breaker) │ └────────────────────────────────────────────────┘ │ ┌───▼───┐ │ 允许? │ └─┬───┬─┘ 是 │ │ 否 ▼ ▼ ✅执行 ❌拒绝+指令: "必须不尝试通过变通方法 实现相同结果"

关键设计参数:

// guardian/mod.rs
pub(crate) const GUARDIAN_REVIEW_TIMEOUT: Duration = Duration::from_secs(90);
pub(crate) const MAX_CONSECUTIVE_GUARDIAN_DENIALS_PER_TURN: u32 = 3;
pub(crate) const MAX_RECENT_AUTO_REVIEW_DENIALS_PER_TURN: u32 = 10;

// 剪枝参数
const GUARDIAN_MAX_MESSAGE_TRANSCRIPT_TOKENS: usize = 10_000;
const GUARDIAN_MAX_TOOL_TRANSCRIPT_TOKENS: usize = 10_000;
const GUARDIAN_MAX_MESSAGE_ENTRY_TOKENS: usize = 2_000;
const GUARDIAN_MAX_TOOL_ENTRY_TOKENS: usize = 1_000;
const GUARDIAN_MAX_ACTION_STRING_TOKENS: usize = 16_000;

Guardian 的拒绝指令非常严格:

const GUARDIAN_REJECTION_INSTRUCTIONS: &str = concat!(
    "The agent must not attempt to achieve the same outcome via workaround, ",
    "indirect execution, or policy circumvention. ",
    "Proceed only with a materially safer alternative, ",
    "or if the user explicitly approves the action after being informed of the risk. ",
    "Otherwise, stop and request user input.",
);
Guardian 的三个核心设计决策:
  1. Fail Closed:超时 = 拒绝,不是允许
  2. Circuit Breaker:连续 3 次拒绝后停止审查,强制交还用户
  3. Anti-Workaround:拒绝后禁止 Agent 尝试替代方案实现相同结果

3.3 Agent Zero Infection Check —— LLM 实时安全审查 Agent Zero

Agent Zero 的 Infection Checker 是另一个 LLM 驱动的安全机制,但审查的是 Agent 的输出而非工具调用:

# plugins/_infection_check/helpers/checker.py

class InfectionChecker:
    """在 Agent 执行每个工具前进行 LLM 安全审查"""

    def __init__(self, config, iteration):
        self.mode = config.get("mode", "thoughts")  # 审查模式
        self.model_choice = config.get("model", "utility")  # 使用的模型
        self.history_size = int(config.get("history_size", 10))
        self.max_clarifications = int(config.get("max_clarifications", 3))

    async def gate(self, agent, tool_name, tool_args):
        """在工具执行前阻塞等待安全检查"""
        # 快速路径:后台任务已完成
        if self._task and self._task.done():
            action, detail, cot = self._task.result()
        # 慢路径:构建完整上下文重新检查
        else:
            snapshot = self._build_log()  # 包含推理、响应、工具参数
            self._task = asyncio.create_task(self._run_check(agent, snapshot))
            action, detail, cot = await self._task

        if action == "ok": return  # ✅ 通过
        if action == "clarify": ...  # ⚠️ 需要澄清
        if action == "terminate": ...  # 🛑 终止

结果解析使用特殊标签:

_RE_OK = re.compile(r"<ok\s*/>")          # 安全
_RE_TERMINATE = re.compile(r"<terminate\s*/>")  # 终止
_RE_CLARIFY = re.compile(r"<clarify>(.*?)</clarify>", re.DOTALL)  # 澄清

4. 注入防护:静态扫描 vs LLM 审查 vs 运行时网关

4.1 Hermes Skills Guard —— 最全面的静态威胁扫描 Hermes

Hermes 的 skills_guard.py 实现了 60+ 威胁模式,覆盖 6 大类攻击:

Hermes Skills Guard 扫描架构 外部 Skill 下载 │ ▼ ┌──────────────────────────────────────────────────────┐ │ Skills Guard Scanner │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Exfiltration │ │ Injection │ │ │ │ env 泄露 │ │ 忽略指令 │ │ │ │ SSH/AWS 访问 │ │ 角色劫持 │ │ │ │ DNS 渗出 │ │ 系统提示提取 │ │ │ │ Markdown 渗出│ │ HTML 隐藏指令│ │ │ └──────────────┘ └──────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Destructive │ │ Persistence │ │ │ │ rm -rf / │ │ crontab │ │ │ │ mkfs, dd │ │ systemd │ │ │ │ chmod 777 │ │ ~/.bashrc │ │ │ │ 覆盖 /etc │ │ SSH key 注入 │ │ │ └──────────────┘ └──────────────┘ │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Network │ │ Obfuscation │ │ │ │ 反向 Shell │ │ base64 编码 │ │ │ │ nc 监听 │ │ eval() │ │ │ │ 端口转发 │ │ exec() │ │ │ └──────────────┘ └──────────────┘ │ │ │ │ 每个 Pattern: (regex, id, severity, category, desc) │ └──────────────────────┬───────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────┐ │ 信任级别与安装策略 │ │ │ │ 来源 │ safe │ caution │ dangerous │ │ ─────────────┼──────┼─────────┼────────── │ │ builtin │ 允许 │ 允许 │ 允许 │ │ trusted* │ 允许 │ 允许 │ 阻止 │ │ community │ 允许 │ 阻止阻止 │ │ agent-created│ 允许 │ 允许 │ 询问 │ │ │ │ * trusted = openai/skills, anthropics/skills only │ └──────────────────────────────────────────────────────┘

部分关键检测模式:

# ── 渗出:Shell 命令泄露密钥 ──
(r'curl\s+[^\n]*\$\{?\w*(KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|API)',
 "env_exfil_curl", "critical", "exfiltration")

# ── 注入:忽略指令 ──
(r'ignore\s+(?:\w+\s+)*(previous|all|above|prior)\s+instructions',
 "prompt_injection_ignore", "critical", "injection")

# ── 注入:隐藏 HTML ──
(r'<!--[^>]*(?:ignore|override|system|secret|hidden)[^>]*-->',
 "html_comment_injection", "high", "injection")

(r'<\s*div\s+style\s*=\s*["\'][\s\S]*?display\s*:\s*none',
 "hidden_div", "high", "injection")

# ── 注入:翻译-执行绕过 ──
(r'translate\s+.*\s+into\s+.*\s+and\s+(execute|run|eval)',
 "translate_execute", "critical", "injection")

# ── 持久化:SSH 密钥注入 ──
(r'authorized_keys|\.ssh/id_rsa',
 "ssh_key_injection", "critical", "persistence")
Hermes Skills Guard 的信任模型设计精妙:builtin 无条件信任 → trusted 仅放行 caution → community 任何发现即阻止。这避免了过度扫描的误报问题——同一模式在不同信任级别下有不同处理策略。

4.2 三种注入防护策略对比

策略 代表项目 优势 局限
静态正则扫描 Hermes Skills Guard 快速、确定性、无 LLM 成本 无法检测语义层面的注入
LLM 审查 Codex Guardian, Agent Zero 理解语义,检测隐蔽注入 有成本、有延迟、可能误判
运行时网关 OpenClaw Policy Pipeline 精确控制、可审计 需预定义策略,无法处理未知攻击
最佳实践:三层纵深防御——静态扫描过滤已知模式(快、确定性),LLM 审查捕获语义攻击(智能但昂贵),运行时网关做最终守门(精确可控)。

5. 工具策略:Allow/Deny/Policy 三层管控

5.1 OpenClaw 三层工具策略 OpenClaw

OpenClaw 对工具的管控是所有项目中最精细的:

OpenClaw 工具策略层级 工具调用请求 │ ▼ ┌──────────────────────────────────────────────────────┐ │ Layer 1: Gateway HTTP Deny │ │ │ │ DEFAULT_GATEWAY_HTTP_TOOL_DENY = [ │ │ "exec", // 直接命令执行 │ │ "spawn", // 子进程创建 │ │ "shell", // Shell 命令 │ │ "fs_write", // 文件写入 │ │ "fs_delete", // 文件删除 │ │ "fs_move", // 文件移动 │ │ "apply_patch", // 补丁应用 │ │ "sessions_spawn", // 代理生成 │ │ "sessions_send", // 跨会话注入 │ │ "cron", // 定时任务控制面 │ │ "gateway", // 网关配置控制面 │ │ "nodes", // 节点命令中继 │ │ ] │ │ │ │ 这些工具在 HTTP API 层直接拒绝,甚至不会到达策略引擎 │ └──────────────────────┬───────────────────────────────┘ │ 通过 ▼ ┌──────────────────────────────────────────────────────┐ │ Layer 2: Sandbox Tool Policy │ │ │ │ DEFAULT_TOOL_ALLOW = [exec, read, write, edit, ...] │ │ DEFAULT_TOOL_DENY = [browser, canvas, nodes, cron, │ │ gateway, *CHANNEL_IDS] │ │ │ │ 支持 glob 模式匹配:tools.sandbox.tools.allow/deny │ │ Agent 级别覆盖 > 全局配置 > 默认值 │ └──────────────────────┬───────────────────────────────┘ │ 通过 ▼ ┌──────────────────────────────────────────────────────┐ │ Layer 3: Trusted Tool Policies (Plugin) │ │ │ │ 插件可以在 beforeToolCall 钩子中: │ │ • 修改工具参数(参数清洗) │ │ • 要求审批(requireApproval) │ │ • 阻止执行(返回阻止结果) │ │ • 限制文件路径访问 │ │ │ │ runTrustedToolPolicies(event, ctx) │ │ → 多个策略顺序执行,任一阻止则终止 │ └──────────────────────────────────────────────────────┘

Trusted Tool Policy 的实现允许插件动态干预工具调用:

// trusted-tool-policy.ts
export async function runTrustedToolPolicies(
  event: PluginHookBeforeToolCallEvent,
  ctx: PluginHookToolContext,
): Promise<PluginHookBeforeToolCallResult | undefined> {
  const policies = getActivePluginRegistry()?.trustedToolPolicies ?? [];

  // 策略可以:
  // 1. 调整参数(参数清洗)
  let adjustedParams = event.params;

  // 2. 要求审批
  let approval: PluginHookBeforeToolCallResult["requireApproval"];

  // 3. 派生路径(如解析 glob 后的实际文件路径)
  const currentDerivedEvent = normalizeDerivedEventFields({ derivedPaths });

  // 多策略顺序执行,每个策略看到前一个策略修改后的结果
  for (const policy of policies) {
    const result = await policy.handler(buildEvent(), ctx);
    if (result?.requireApproval) approval = result.requireApproval;
    if (result?.adjustedParams) { adjustedParams = result.adjustedParams; }
    if (result?.blocked) return result;  // 立即阻止
  }
}

5.2 Codex CLI Permission Profile Codex CLI

Codex CLI 的权限配置文件 (Permission Profile) 将文件系统和网络权限统一管理:

// 三级权限配置
pub enum PermissionProfile {
    ReadOnly,   // 所有文件只读
    Workspace,  // 工作区内读写,外部只读
    FullAccess, // 危险:完全访问
}

// 网络策略
pub struct NetworkSandboxPolicy {
    mode: NetworkMode,        // Disabled / AllowDomains / ProxyAll
    allowed_domains: Vec<String>,
    unix_socket_permissions: Vec<NetworkUnixSocketPermission>,
}

// 文件系统策略
pub struct FileSystemSandboxPolicy {
    entries: Vec<FileSystemSandboxEntry>,  // 每个路径的独立权限
    special_paths: Vec<FileSystemSpecialPath>,
}
工具策略设计原则:
  1. 默认最小权限:新工具默认 deny,需显式 allow
  2. 分层覆盖:HTTP 网关 → 沙箱策略 → 插件策略,层层收紧
  3. 可审计:每个策略决策记录来源(global/agent/default)
  4. 路径级管控:不只控制"能不能用",还控制"能用在什么上"

6. 安全审计:配置扫描与合规检查

6.1 OpenClaw Security Audit OpenClaw

OpenClaw 提供了最全面的安全审计系统,通过 openclaw security audit 命令运行:

$ openclaw security audit           # 基础审计
$ openclaw security audit --deep    # 深度审计(包含 Gateway 探测)
$ openclaw security audit --fix     # 自动修复安全问题
$ openclaw security audit --json    # 机器可读输出

审计检查项来自 audit-extra.sync.ts,覆盖 1100+ 行检查逻辑:

审计检查项示例

审计结果类型:

export type SecurityAuditFinding = {
  checkId: string;                  // 检查项 ID
  severity: "info" | "warn" | "critical";  // 严重程度
  title: string;                    // 标题
  detail: string;                   // 详情
  remediation?: string;             // 修复建议
};

6.2 AutoGPT Security Headers AutoGPT

AutoGPT 在 Web API 层实现了安全头中间件:

# backend/api/middleware/security.py
class SecurityHeadersMiddleware:
    """添加安全响应头,默认禁用所有缓存"""

    CACHEABLE_PATHS = {
        "/static", "/_next/static",  # 静态资源
        "/api/health", "/api/status", # 健康检查
        "/api/store/agents",          # 公共市场
        "/api/graphs/templates",      # 图模板
    }

    # 默认不可缓存 → 防止敏感 Agent 数据被中间层缓存

7. 运行时防护:ReDoS、凭证泄露、卡死检测

7.1 OpenClaw Safe Regex —— ReDoS 防护 OpenClaw

正则表达式拒绝服务 (ReDoS) 是 Agent 系统的特殊风险——Agent 可能从外部内容中构建正则表达式:

// security/safe-regex.ts — 完整的 ReDoS 防护

// 核心检测:嵌套量词分析
export function hasNestedRepetition(source: string): boolean {
  // 示例:(a+)+ → 危险:嵌套重复
  // 示例:(a|b)* → 危险:模糊交替 + 无限重复
  return analyzeTokensForNestedRepetition(tokenizePattern(source));
}

// 安全编译:拒绝危险正则
export function compileSafeRegexDetailed(source: string, flags = "") {
  if (hasNestedRepetition(trimmed)) {
    return { regex: null, reason: "unsafe-nested-repetition" };
  }
  try {
    return { regex: new RegExp(trimmed, flags), reason: null };
  } catch {
    return { regex: null, reason: "invalid-regex" };
  }
}

// 有界输入测试:限制测试窗口
export function testRegexWithBoundedInput(
  regex: RegExp,
  input: string,
  maxWindow = 2048,  // 最多测试前后 2048 字符
): boolean {
  if (input.length <= maxWindow) {
    return regex.test(input);
  }
  // 仅测试头部和尾部
  return regex.test(input.slice(0, maxWindow)) ||
         regex.test(input.slice(-maxWindow));
}

实现了一个完整的正则表达式 token 化器,支持:

通过计算最小/最大匹配长度和嵌套重复检测来识别 ReDoS 风险模式。

7.2 OpenClaw Dangerous Tools Registry OpenClaw

集中管理危险工具列表,避免安全策略和审计逻辑漂移:

// security/dangerous-tools.ts
export const DEFAULT_GATEWAY_HTTP_TOOL_DENY = [
  "exec",           // 直接 RCE
  "spawn",          // 子进程 RCE
  "shell",          // Shell RCE
  "fs_write",       // 任意文件写入
  "fs_delete",      // 任意文件删除
  "fs_move",        // 任意文件移动
  "apply_patch",    // 补丁可重写任意文件
  "sessions_spawn", // 远程代理生成 = RCE
  "sessions_send",  // 跨会话消息注入
  "cron",           // 持久化自动化控制面
  "gateway",        // 网关重配置
  "nodes",          // 节点命令中继
] as const;

7.3 Smolagents Python 沙箱防护 Smolagents

Smolagents 在 Python 执行器中实现了返回值安全检查:

# safer_eval 装饰器 — 检查评估函数的返回值
@wraps(func)
def _check_return(expression, state, static_tools, custom_tools,
                  authorized_imports=BASE_BUILTIN_MODULES):
    result = func(expression, state, static_tools, custom_tools,
                  authorized_imports=authorized_imports)
    check_safer_result(result, static_tools, authorized_imports)
    return result

# safer_func 装饰器 — 检查普通函数的返回值
@wraps(func)
def _check_return(*args, **kwargs):
    result = func(*args, **kwargs)
    check_safer_result(result, static_tools, authorized_imports)
    return result

这防止了 Agent 通过合法函数调用链获取危险对象(如文件句柄、子进程对象等)。

8. 对比矩阵

项目 沙箱 审批系统 注入防护 安全审计 工具策略
OpenClaw Docker (30+ 配置项) 多层审批 + 原生 UI Policy Pipeline + Plugin ✅ 1100+ 行检查 ✅ 三层 Allow/Deny/Policy
Codex CLI Docker + Seatbelt + Win ✅ LLM Guardian Guardian + Permission Profile ✅ 三级 Profile
Hermes ✅ 60+ 静态模式 Trust Level 策略
OpenHands ✅ Docker 沙箱
Agent Zero LLM Infection Check ✅ LLM 输出审查
Smolagents Python 解释器沙箱 返回值安全检查 authorized_imports
AutoGPT Security Headers Block 白名单
SWE-agent Docker (容器内执行)
Aider
LangGraph
安全赤字:20 个项目中,只有 OpenClaw 和 Codex CLI 实现了完整的安全体系(沙箱+审批+注入防护+审计+工具策略)。大多数项目只实现了其中 1-2 项,甚至完全没有安全机制。Agent 安全远未成为行业标配。

9. 模式提炼与最佳实践

9.1 纵深防御模型

综合所有项目的安全实现,我们提炼出 Agent 安全的 5 层纵深防御模型:

Agent 安全纵深防御模型 外部输入 ──────────────────────────────────────────→ Agent │ │ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ L1: 静态扫描 │ │ L5: 沙箱隔离 │ │ 已知恶意模式 │ │ 物理隔离 │ │ 正则 + 启发式 │ │ Docker/Seatbelt│ │ (Hermes) │ │ (OpenClaw) │ └──────┬───────┘ └──────────────┘ │ ▲ ▼ │ ┌──────────────┐ ┌──────────────┐ │ L2: 网关过滤 │ │ L4: 运行时审批 │ │ HTTP API 限制 │ │ 人/LLM 审批 │ │ 工具调用路由 │ │ Guardian/Gate │ │ (OpenClaw) │ │ (Codex/A0) │ └──────┬───────┘ └──────────────┘ │ ▲ ▼ │ ┌──────────────┐ ┌──────────────┐ │ L3: 策略引擎 │────────────────────────→│ │ │ Allow/Deny │ 工具调用请求 │ │ │ 路径限制 │ 未匹配策略 │ │ │ (OpenClaw) │ │ │ └──────────────┘ └──────────────┘

9.2 LLM 安全审查的设计要点

基于 Codex Guardian 和 Agent Zero Infection Check 的经验:

✅ 必须做到

  1. Fail Closed:超时、错误、解析失败 → 一律拒绝
  2. Circuit Breaker:连续拒绝后停止审查,防止 Agent 反复试探
  3. Anti-Workaround:拒绝后禁止变通实现相同结果
  4. 上下文剪枝:审查会话只保留必要上下文(Guardian 限制 10K tokens)
  5. 独立模型:审查用模型应与主 Agent 不同,避免同源偏见

❌ 必须避免

  1. Fail Open:审查超时时默认允许 → Agent 可以通过制造超时绕过
  2. Self-Review:让 Agent 审查自己的操作 → 天然利益冲突
  3. 无限重试:被拒绝后允许无限次重新提交 → 概率性通过
  4. 忽略间接路径:只检查直接命令,忽略 Agent 可能通过多步操作实现同样结果
  5. 无审计日志:审查决策不可追溯 → 无法事后分析安全事件

9.3 沙箱配置最佳实践

OpenClaw 沙箱安全清单

  1. readOnlyRoot: true — 只读根文件系统
  2. network: "none" — 禁用网络(除非需要)
  3. capDrop: ["ALL"] — 丢弃所有 Linux capabilities
  4. pidsLimit: 100 — 限制进程数(防 fork bomb)
  5. memory: "2g" — 内存限制
  6. seccompProfile — 系统调用过滤
  7. apparmorProfile — 强制访问控制
  8. dangerouslyAllow* — 仅在充分理解风险时启用
  9. network: "host" — 几乎不应使用
  10. binds: ["/:/host"] — 永远不要挂载根目录

9.4 安全设计原则总结

🛡️ Agent 安全 7 原则

  1. 默认拒绝,显式允许 — 新操作、新工具、新路径默认禁止
  2. 纵深防御 — 单一防线必然被突破,需要多层叠加
  3. 最小权限 — 只给 Agent 完成任务所需的最少权限
  4. Fail Closed — 任何不确定情况都应拒绝而非允许
  5. 可审计 — 每个安全决策都要有来源和日志
  6. 隔离不可信输入 — 来自外部的所有内容都应视为潜在的注入载体
  7. 人始终在环 — 对于破坏性操作,最终决策权在人类
核心洞察:Agent 安全不是一个技术问题,而是一个架构问题。OpenClaw 和 Codex CLI 之所以安全,不是因为某个单一机制,而是因为安全被嵌入到架构的每一层——从 HTTP 网关到 Docker 沙箱,从工具策略到审批系统,从静态扫描到 LLM 审查。其他项目之所以不安全,不是因为缺少某个技术,而是因为安全从未成为架构设计的一等公民。

🔗 构建 Agent 实践指南 · 主循环 · 工具系统 · 记忆系统 · 提示词工程

📊 数据来源:20 个 Agent 项目源码分析 · 2026-05