Skip to content

OpenClaw 源码解读(十二)安全系统

本篇深入分析 OpenClaw 的安全体系,涵盖认证授权、SSRF 防护、命令执行安全、设备身份、密钥管理、安全审计等核心机制。安全系统是 OpenClaw 最精密的工程之一,涉及 50+ 个源文件,代码量超过 8000 行。


目录


一、安全系统全景

1.1 安全哲学

OpenClaw 的安全设计遵循一个核心原则:安全的默认值 + 可选的能力放开。用户必须显式选择放开安全限制(opt-in),而非默认暴露后再关闭(opt-out)。

其信任模型的核心假设:

  • 操作者信任:安装并运行 OpenClaw 的用户被视为可信
  • 单用户设计main 会话拥有主机的完全访问权限
  • 入站不信任:来自外部消息渠道的 DM 默认视为不可信输入
  • 深度防御:多层安全检查叠加,单一防线失效不会导致全面沦陷

1.2 安全子系统分布

安全系统
├── src/security/              ← 安全审计引擎 + DM 策略 + 危险标志
├── src/gateway/auth*.ts       ← 网关认证(多模式)+ 频率限制
├── src/infra/device-*.ts      ← 设备身份(Ed25519)+ Token 存储
├── src/infra/net/ssrf.ts      ← SSRF 防护 + DNS 钉住
├── src/infra/exec-*.ts        ← 命令执行审批 + 白名单 + 混淆检测
├── src/infra/fs-safe.ts       ← 安全文件操作
├── src/infra/path-guards.ts   ← 路径安全守卫
├── src/secrets/               ← 密钥解析 + 审计 + SecretRef
├── src/agents/sandbox/        ← Docker 沙箱安全验证
├── src/browser/               ← 浏览器导航守卫 + 控制面板认证
└── src/cli/security-cli.ts    ← `openclaw security audit` 命令

![安全系统全景:核心哲学、信任模型与安全子系统分布](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/01-infographic-security-overview-1775150767530.png)


二、认证与授权

2.1 时序安全的密钥比较 (src/security/secret-equal.ts)

这是整个认证体系的基石,仅 12 行代码,但蕴含了关键的安全原理:

typescript
import { createHash, timingSafeEqual } from "node:crypto";

export function safeEqualSecret(
  provided: string | undefined | null,
  expected: string | undefined | null,
): boolean {
  if (typeof provided !== "string" || typeof expected !== "string") {
    return false;
  }
  const hash = (s: string) => createHash("sha256").update(s).digest();
  return timingSafeEqual(hash(provided), hash(expected));
}

为什么需要这个函数?

普通的 === 比较会在发现第一个不匹配字符时立即返回 false。攻击者可以通过精确测量比较时间来逐字节推断正确的密钥——这就是时序攻击(Timing Attack)

两层防护:

  1. SHA-256 哈希:将两个字符串都哈希为固定 32 字节,确保 timingSafeEqual 的输入长度一致(timingSafeEqual 要求两个 Buffer 等长)
  2. timingSafeEqual:Node.js 提供的恒定时间比较,无论输入如何,比较时间完全相同

2.2 网关多模式认证 (src/gateway/auth.ts)

Gateway 支持四种认证模式,覆盖从本地开发到生产部署的各种场景:

模式适用场景安全级别
none仅本地回环(127.0.0.1)最低
tokenAPI 集成、设备连接
passwordFunnel/远程访问中高
trusted-proxy反向代理后(Nginx/Caddy)取决于代理

认证决策流程:

HTTP/WS 请求到达

    ├─ [trusted-proxy?] → 验证来源 IP + 代理头部 + 用户身份头部

    ├─ [none?] → 仅允许 loopback 地址,直接放行

    ├─ 速率限制检查 → 是否被锁定?

    ├─ [Tailscale?] → 调用 Tailscale Whois 验证身份

    ├─ [token?] → safeEqualSecret(请求token, 配置token)

    ├─ [password?] → safeEqualSecret(请求密码, 配置密码)

    └─ → 返回 GatewayAuthResult { ok, role, identity }

关键安全约束: 禁止明文 ws:// 连接到非 loopback 地址(CWE-319, CVSS 9.8)。

2.3 认证频率限制 (src/gateway/auth-rate-limit.ts)

基于内存的滑动窗口频率限制器,防止暴力破解攻击:

typescript
export function createAuthRateLimiter(config?: RateLimitConfig): AuthRateLimiter {
  const maxAttempts = config?.maxAttempts ?? 10;     // 默认 10 次
  const windowMs = config?.windowMs ?? 60_000;       // 1 分钟窗口
  const lockoutMs = config?.lockoutMs ?? 300_000;    // 锁定 5 分钟
  const exemptLoopback = config?.exemptLoopback ?? true; // 本地回环豁免
  // ...
}

核心设计:

  • 滑动窗口:不是简单的"每分钟 N 次",而是维护每次失败的时间戳数组,精确地滑动清理过期记录
  • 作用域隔离:按 {scope, clientIp} 独立计数,shared-secret、device-token、hook-auth 互不干扰
  • 本地回环豁免127.0.0.1 / ::1 永远不会被锁定,防止本地 CLI 被意外封锁
  • 定期清理:60 秒后台清理已过期的条目,防止 Map 无限增长
  • unref() 计时器:清理定时器不阻止 Node.js 进程退出

2.4 启动认证 (src/gateway/startup-auth.ts)

Gateway 启动时的认证保障:

  • 如果没有配置 token,自动生成安全随机 token 并持久化
  • 校验 hooks token 和 gateway token 必须分离(防止密钥复用)
  • 解析 SecretRef 类型的密码配置
  • 确保启动时有有效的认证凭证

![认证与授权系统:时序安全比较、四种认证模式与频率限制](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/02-infographic-auth-system-1775150768314.png)


三、设备身份系统

3.1 Ed25519 密钥对管理 (src/infra/device-identity.ts)

每个 OpenClaw 设备(macOS 客户端、iOS 节点、CLI 等)都有一个唯一的加密身份:

typescript
function generateIdentity(): DeviceIdentity {
  const { publicKey, privateKey } = crypto.generateKeyPairSync("ed25519");
  const publicKeyPem = publicKey.export({ type: "spki", format: "pem" }).toString();
  const privateKeyPem = privateKey.export({ type: "pkcs8", format: "pem" }).toString();
  const deviceId = fingerprintPublicKey(publicKeyPem); // SHA-256(公钥原始字节)
  return { deviceId, publicKeyPem, privateKeyPem };
}

为什么选择 Ed25519?

特性Ed25519RSA-2048
密钥长度32 字节256 字节
签名速度极快较慢
安全性128 位等效112 位等效
抗量子否(同 RSA)

设备 ID 派生链:

Ed25519 公钥 (PEM)
    → 导出 SPKI DER 格式
    → 去掉 12 字节 SPKI 前缀 → 得到 32 字节原始公钥
    → SHA-256 哈希
    → 十六进制编码 → deviceId

文件权限保护: 密钥文件写入时强制 mode: 0o600(仅所有者可读写),写入后再 chmodSync(filePath, 0o600) 双重保障。

3.2 设备认证协议 (src/gateway/device-auth.ts)

设备连接 Gateway 时采用 Challenge-Response 握手:

客户端                                    Gateway
  │                                         │
  ├── ws connect + deviceId ──────────────►│
  │                                         │
  │◄──────────── challenge nonce ──────────┤
  │                                         │
  ├── sign(privateKey, nonce+timestamp) ──►│
  │                                         │
  │◄──────── verify(publicKey, sig) ───────┤
  │                                         │
  │        连接建立 / 拒绝                   │

v2/v3 认证载荷包含: deviceIdclientIdscopes(权限范围)、签名时间戳、nonce(防重放)。

3.3 Token 持久化 (src/infra/device-auth-store.ts)

设备认证令牌存储在 ~/.openclaw/device-auth.json,按角色(role)存储/加载/清除:

  • 文件权限 0o600
  • 支持多角色 token 共存
  • 读取时做完整的 JSON 校验和类型检查

![设备身份系统:Ed25519 密钥生成、对比与 Challenge-Response 协议](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/03-infographic-device-identity-1775150769082.png)


四、SSRF 防护链

4.1 核心原理 (src/infra/net/ssrf.ts)

SSRF(Server-Side Request Forgery)是 Web 应用最常见的高危漏洞之一。攻击者可以利用服务端发起请求的能力,访问内网服务、云实例元数据等。

OpenClaw 的 SSRF 防护是一个多层检查链

用户提供 URL

    ├─ Layer 1: 协议检查 → 仅允许 http/https

    ├─ Layer 2: 主机名黑名单 → 阻止 localhost、*.local、*.internal、
    │                            metadata.google.internal 等

    ├─ Layer 3: IP 地址分类 → 阻止私有/保留/特殊用途 IP
    │   ├─ IPv4: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16,
    │   │        127.0.0.0/8, 169.254.0.0/16, 0.0.0.0/8 等
    │   ├─ IPv6: ::1, fc00::/7, fe80::/10, ::ffff:0:0/96(映射的 IPv4)
    │   └─ IPv4-mapped-IPv6 嵌入检测

    ├─ Layer 4: DNS 解析后二次验证 → 防止 DNS Rebinding
    │   └─ 解析出的所有 IP 地址都必须通过 Layer 3 检查

    └─ Layer 5: DNS 钉住(Pinned Lookup)→ 防止 TOCTOU
        └─ DNS 查询结果绑定到连接,确保实际连接的 IP 就是检查过的 IP

4.2 DNS Rebinding 防护

DNS Rebinding 攻击:攻击者控制一个域名,第一次解析返回公网 IP(通过安全检查),第二次解析返回 127.0.0.1(实际连接时访问内网)。

OpenClaw 的防御:

typescript
// 第一步:解析 DNS
const addresses = await dnsLookup(hostname);

// 第二步:验证所有解析结果
assertAllowedResolvedAddressesOrThrow(addresses, policy);

// 第三步:创建 Pinned Lookup,将验证过的 IP 固定到后续连接
const pinnedLookup = createPinnedLookup({
  hostname,
  addresses: addresses.map(a => a.address),
});
// 后续 fetch 使用此 pinnedLookup,确保连接的 IP 就是验证过的

4.3 特殊 IP 格式防御

攻击者经常用非标准 IP 表示法绕过简单的字符串匹配:

绕过技巧示例OpenClaw 防御
八进制 IPv40177.0.0.1 (= 127.0.0.1)isLegacyIpv4Literal 检测
十六进制 IPv40x7f000001looksLikeUnsupportedIpv4Literal
IPv4-mapped IPv6::ffff:127.0.0.1extractEmbeddedIpv4FromIpv6
畸形 IPv6含有无效格式的地址Fail Closed — 解析失败视为私有地址

核心原则:Fail Closed — 任何无法正确解析的地址都被视为不安全,宁可误杀不可放过。

4.4 受保护的 HTTP 请求 (src/infra/net/fetch-guard.ts)

为 Agent 工具调用提供安全的 fetch 封装:

  • strict 模式:完整的 SSRF 检查链
  • trusted_env_proxy 模式:信任环境代理配置
  • 自动 DNS 钉住 + 重定向跟踪 + 超时控制

![SSRF 五层防护链:协议检查、黑名单、IP 分类、DNS 验证与钉住](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/04-infographic-ssrf-protection-1775150769890.png)


五、命令执行安全

5.1 三层安全策略 (src/infra/exec-approvals.ts)

Agent 执行 shell 命令是最高风险的操作。OpenClaw 提供三种安全策略:

策略行为适用场景
deny拒绝所有命令(默认)高安全要求
allowlist仅允许白名单中的命令生产环境推荐
full允许所有命令开发/信任环境

审批交互模式(ask):

  • off:不询问,直接按策略执行
  • on-miss:不在白名单中时询问用户(默认)
  • always:每次都询问

5.2 命令白名单匹配 (src/infra/exec-approvals-allowlist.ts)

白名单不是简单的字符串匹配,而是经过完整的命令解析后匹配:

用户命令: "git push origin main"

    ├─ Shell 解析 → ["git", "push", "origin", "main"]
    ├─ 命令路径解析 → /usr/bin/git
    ├─ Shell wrapper 解包 → 检测 bash -c "..." 等
    ├─ 白名单模式匹配 → "git *" 或 "git push *"
    └─ 决策: allow/deny

5.3 命令混淆检测 (src/infra/exec-obfuscation-detect.ts)

防止攻击者通过编码手段绕过白名单:

混淆技巧检测方式
echo "Y21k" | base64 -d | sh检测 base64 + 管道执行
printf "\x63\x6d\x64" | sh检测 printf hex + 管道执行
eval $(echo "cmd")检测 eval + 命令替换
$'\x63\x6d\x64'检测 ANSI-C 引号编码

5.4 安全二进制策略 (src/infra/exec-safe-bin-policy.ts)

对常见命令定义细粒度的参数验证规则:

安全命令 (safe-bin)
├── ls     → 允许 -l, -a, -h 等读取标志
├── cat    → 允许任意文件路径参数
├── grep   → 允许 -r, -n, -i 等搜索标志
├── git    → 允许 status, diff, log 等只读子命令
├── node   → 限制可执行的脚本路径
└── ...

信任路径验证 (src/infra/exec-safe-bin-trust.ts):命令的绝对路径必须位于可信系统目录中(如 /usr/bin/usr/local/bin),防止 PATH 注入攻击。

5.5 宿主环境变量安全 (src/infra/host-env-security.ts)

Agent 执行命令时,环境变量经过严格过滤:

typescript
function sanitizeHostExecEnv(env: Record<string, string>): Record<string, string> {
  // 阻止的危险变量:
  // - LD_PRELOAD / LD_LIBRARY_PATH (Linux 动态链接器劫持)
  // - DYLD_INSERT_LIBRARIES / DYLD_* (macOS 动态链接器劫持)
  // - NODE_OPTIONS (注入 Node.js 启动参数)
  // - PATH (防止覆盖系统 PATH)
  // ...
}

![命令执行安全:三层策略、审批流程与混淆检测](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/05-infographic-exec-security-1775150770641.png)


六、文件系统安全

6.1 路径边界守卫 (src/infra/path-guards.ts)

防止路径遍历攻击(Directory Traversal):

typescript
// isPathInside: 检查 childPath 是否在 parentPath 内部
isPathInside("/home/user/.openclaw/config.json", "/home/user/.openclaw")  // true
isPathInside("/etc/passwd", "/home/user/.openclaw")                       // false
isPathInside("/home/user/.openclaw/../../../etc/passwd", "/home/user/.openclaw") // false

6.2 符号链接 & 硬链接防护

攻击向量防御文件防御方式
符号链接逃逸path-alias-guards.tsassertNoPathAliasEscape 检测链接目标是否逃出工作区
硬链接绕过hardlink-guards.tsstat.nlink > 1 检测多链接文件
TOCTOU 竞态fs-safe.ts多次校验:lstat → open → stat → realpath → stat
原子写入fs-safe.ts先写临时文件再 rename(原子操作)

6.3 安全文件操作 (src/infra/fs-safe.ts)

这是整个项目安全设计最精华的文件之一(~500 行):

安全文件打开流程:
    lstat(path)                    ← 检查是否为符号链接
    → open(path, O_NOFOLLOW)       ← 禁止跟随符号链接
    → fstat(fd)                    ← 检查 nlink > 1(硬链接)
    → realpath(path)               ← 解析真实路径
    → isPathInside(realpath, root) ← 验证路径在边界内
    → stat(realpath)               ← 最终确认
    → 读取/写入

平台差异处理:

  • Linux: 通过 /proc/self/fd/N 访问文件描述符路径
  • macOS: 通过 /dev/fd/N 访问

![文件系统安全:安全文件打开流程与四种攻击防御](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/06-infographic-filesystem-security-1775150771850.png)


七、密钥管理系统

7.1 SecretRef 多源解析 (src/secrets/resolve.ts)

OpenClaw 的密钥不直接存储在配置文件中,而是通过 SecretRef 引用外部来源:

jsonc
{
  "channels": {
    "telegram": {
      "token": {
        // SecretRef: 从环境变量读取
        "source": "env",
        "provider": "default",
        "id": "TELEGRAM_BOT_TOKEN"
      }
    }
  }
}

三种密钥来源:

来源说明安全级别
env环境变量中(依赖进程隔离)
file文件读取高(文件权限控制)
exec命令执行输出高(如 op read 1Password)

解析安全保障:

typescript
// 文件来源的密钥读取前,会进行路径安全验证:
async function assertSecurePath(params) {
  // 1. 必须是绝对路径
  // 2. 不能是目录
  // 3. 不能是符号链接(除非 allowSymlinkPath)
  // 4. 必须在 trustedDirs 内(如果配置了)
  // 5. 文件权限不能过于开放(不允许 group/world 可读写)
  // 6. 文件所有者必须是当前用户或 root
}

资源限制:

  • 并发限制:默认 4 个 provider 并发
  • 引用限制:每个 provider 最多 512 个 ref
  • 批量字节限制:256KB
  • 文件/执行超时:5 秒

7.2 配置脱敏 (src/config/redact-snapshot.ts)

导出或展示配置时,自动脱敏敏感字段:

原始配置: { "token": "sk-ant-api03-xxx..." }
    ↓ redactConfigSnapshot()
脱敏输出: { "token": "<redacted>" }

脱敏规则覆盖:passwordtokenapiKeyappSecretwebhookSecret 等所有已知敏感字段名。

7.3 密钥审计 (src/secrets/audit.ts)

openclaw security audit 会检测:

  • 明文密钥(直接写在配置文件中的 API Key)
  • 未解析的 SecretRef(指向不存在的环境变量/文件)
  • 被遮蔽的引用(配置中的值与环境变量冲突)
  • 遗留认证残留(旧版本配置中的密钥痕迹)

![密钥管理系统:SecretRef 三种来源、安全检查与资源限制](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/07-infographic-secret-management-1775150772589.png)


八、DM 私信策略与配对

8.1 DM 策略决策 (src/security/dm-policy-shared.ts)

当外部用户通过消息渠道(Telegram/Discord/WhatsApp 等)发送私信时,OpenClaw 需要决定是否响应:

typescript
export type DmGroupAccessDecision = "allow" | "block" | "pairing";

四种 DM 策略:

策略行为风险
disabled完全禁用 DM最安全
pairing未知用户需要配对验证(默认)安全
allowlist仅允许白名单中的用户安全
open允许所有人(危险)高风险

决策流程(以收到群组消息为例):

收到群组消息

    ├─ [groupPolicy=disabled?] → block (群组策略已禁用)

    ├─ [groupPolicy=allowlist?]
    │   ├─ 白名单为空? → block (空白名单)
    │   ├─ 发送者在白名单? → allow
    │   └─ 发送者不在? → block

    └─ → allow (其他策略)

DM 策略(以收到私信为例):

收到私信

    ├─ [dmPolicy=disabled?] → block

    ├─ [dmPolicy=open?] → allow (危险!)

    ├─ 发送者在白名单? → allow (包括配对存储中的用户)

    ├─ [dmPolicy=pairing?] → 发送配对码,等待管理员审批

    └─ → block

8.2 白名单来源融合

有效白名单 = 配置白名单 ∪ 配对存储白名单:

typescript
const effectiveAllowFrom = mergeDmAllowFromSources({
  allowFrom,          // 配置文件中的 allowFrom 列表
  storeAllowFrom,     // 通过配对审批后存储的用户列表
  dmPolicy,           // 当前 DM 策略
});

8.3 命令权限隔离

即使用户被允许发消息,控制命令(如 /restart)有额外的权限检查:

typescript
// 群组命令授权不继承 DM 配对存储的批准
const commandDmAllowFrom = params.isGroup ? configuredAllowFrom : access.effectiveAllowFrom;

![DM 私信策略:四种策略、决策流程与白名单融合](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/08-infographic-dm-policy-1775150773422.png)


九、安全审计引擎

9.1 审计报告结构 (src/security/audit.ts)

typescript
type SecurityAuditReport = {
  ts: number;                           // 审计时间戳
  summary: {
    critical: number;                   // 严重级别数量
    warn: number;                       // 警告级别数量
    info: number;                       // 信息级别数量
  };
  findings: SecurityAuditFinding[];     // 审计发现列表
  deep?: { gateway?: { ... } };        // 深度探测结果
};

type SecurityAuditFinding = {
  checkId: string;                      // 如 "fs.state_dir.perms_world_writable"
  severity: "info" | "warn" | "critical";
  title: string;                        // 人类可读标题
  detail: string;                       // 详细描述
  remediation?: string;                 // 修复建议
};

9.2 审计检查项分类

文件系统审计 (audit-fs.ts):

  • 状态目录(~/.openclaw)权限检查
  • 配置文件权限检查
  • 符号链接检测
  • World-writable / Group-writable 检测
  • Windows ACL 检查(icacls

渠道安全审计 (audit-channel.ts):

  • 各渠道的 DM 策略配置检查
  • Webhook 安全配置
  • Bot Token 暴露风险
  • allowFrom 配置完整性

同步审计 (audit-extra.sync.ts):

  • 危险配置标志(dangerously* 前缀)
  • exec 安全策略检查
  • 文件系统工作区限制
  • 沙箱配置验证
  • 插件信任级别
  • 模型安全卫生检查

异步审计 (audit-extra.async.ts):

  • 网关 HTTP 探测(--deep 模式)
  • 活跃连接检查
  • 远程配置验证
  • 安全码(code safety)扫描

9.3 CLI 命令

bash
# 基础审计
openclaw security audit

# 深度审计(包含运行时探测)
openclaw security audit --deep

# 输出 JSON 格式
openclaw security audit --json

# 自动修复可修复的问题
openclaw security audit --fix

9.4 自动修复引擎 (src/security/fix.ts)

--fix 模式可以自动修复:

  • 文件权限过于开放 → 收紧到 0o600 / 0o700
  • 配置中的明文密钥 → 建议迁移到 SecretRef
  • 缺少关键安全配置 → 添加安全默认值

![安全审计引擎:报告结构、四类审计检查与自动修复](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/09-infographic-audit-engine-1775150774177.png)


十、安全正则与 ReDoS 防护

10.1 ReDoS 攻击原理

正则表达式拒绝服务(ReDoS):精心构造的输入可以让某些正则表达式的匹配时间呈指数级增长。例如:

正则: /^(a+)+$/
输入: "aaaaaaaaaaaaaaaaab"
→ 匹配时间:O(2^n),n = 'a' 的个数

10.2 安全正则验证 (src/security/safe-regex.ts)

OpenClaw 实现了一个自定义的正则表达式安全分析器(~190 行),用于检测用户配置中可能导致 ReDoS 的正则:

正则源码
    → tokenizePattern()          ← 词法分析
    → analyzeTokensForNestedRepetition()  ← 检测嵌套量词
        ├─ (a+)+  → 危险!嵌套重复
        ├─ (a|b)* → 安全(交替分支长度一致)
        └─ (a|ab)* → 危险!交替分支长度不一致 + 重复
    → 缓存结果(LRU, 256 条上限)
    → 运行时测试窗口:2048 字符

检测的核心模式: 嵌套量词(quantifier applied to token that already contains repetition)。这是 ReDoS 的根本原因。

![安全正则与 ReDoS 防护:攻击原理与安全分析器](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/10-infographic-redos-protection-1775150775024.png)


十一、沙箱安全验证

11.1 Docker 沙箱配置检查 (src/agents/sandbox/validate-sandbox-security.ts)

当配置 Docker 沙箱运行 Agent 时,验证 Docker 配置是否安全:

检查项阻止的危险配置原因
敏感主机路径挂载-v /:/host容器可访问整个宿主文件系统
Seccomp 未限制--security-opt seccomp=unconfined容器可执行所有系统调用
AppArmor 未限制--security-opt apparmor=unconfined绕过强制访问控制
危险网络模式--network host容器共享宿主网络栈
特权模式--privileged容器获得几乎全部宿主权限

11.2 浏览器安全 (src/browser/)

  • 导航守卫 (navigation-guard.ts):浏览器工具访问 URL 前,复用 SSRF 防护链验证目标安全性
  • 控制面板认证 (control-auth.ts):浏览器控制面板复用 Gateway auth token,防止未授权访问

![沙箱安全验证:Docker 五项检查与浏览器安全机制](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/11-infographic-sandbox-security-1775150775919.png)


十二、模块关系与设计总结

12.1 安全模块依赖图

                    ┌─────────────────────────────────┐
                    │     openclaw security audit      │
                    │      (CLI 命令入口)               │
                    └───────────────┬─────────────────┘

                    ┌───────────────▼─────────────────┐
                    │        audit.ts (审计编排)        │
                    └──┬────┬────┬────┬───────────────┘
                       │    │    │    │
          ┌────────────▼┐ ┌▼──┐ ┌▼──┐ ┌▼──────────────┐
          │audit-channel│ │fs │ │sync│ │   async       │
          │ (渠道审计)  │ │   │ │    │ │(运行时探测)   │
          └──────┬──────┘ └───┘ └─┬──┘ └───────────────┘
                 │                │
    ┌────────────▼────────────────▼─────────────────────┐
    │              被审计的安全子系统                      │
    ├────────────┬────────────┬────────────┬─────────────┤
    │ Gateway    │ 设备身份   │ SSRF 防护  │ 命令执行    │
    │ Auth       │ Ed25519    │ DNS 钉住   │ 白名单      │
    ├────────────┼────────────┼────────────┼─────────────┤
    │ DM 策略    │ 文件系统   │ 密钥管理   │ 沙箱验证    │
    │ 配对       │ 路径守卫   │ SecretRef  │ Docker      │
    └────────────┴────────────┴────────────┴─────────────┘

                    ┌─────────▼──────────────┐
                    │   secret-equal.ts       │
                    │ (时序安全比较 — 基石)    │
                    └─────────────────────────┘

12.2 关键设计模式

模式应用说明
Fail ClosedSSRF IP 解析解析失败 → 视为不安全
深度防御文件操作、命令执行多层检查叠加
最小权限DM 策略默认 pairing默认不信任
时序安全safeEqualSecret恒定时间比较
依赖注入审计引擎所有外部依赖可测试替换
滑动窗口频率限制精确的时间窗口管理
原子操作文件写入tmp → rename
资源限制密钥解析并发/大小/超时控制

12.3 安全文件清单(按阅读优先级)

优先级文件行数难度
🔴 必读security/secret-equal.ts~12★☆☆☆☆
🔴 必读gateway/auth-rate-limit.ts~232★★★☆☆
🔴 必读infra/device-identity.ts~182★★★☆☆
🟡 推荐security/dm-policy-shared.ts~320★★★☆☆
🟡 推荐infra/net/ssrf.ts~363★★★★☆
🟡 推荐gateway/auth.ts~487★★★★☆
🟡 推荐infra/exec-approvals.ts~420★★★★☆
🟢 选读security/audit.ts~690★★★★☆
🟢 选读secrets/resolve.ts~350★★★★☆
🟢 选读security/safe-regex.ts~190★★★★★
🟢 选读infra/exec-obfuscation-detect.ts~130★★★☆☆
🟢 选读infra/fs-safe.ts~500★★★★★

12.4 思考题

  1. 为什么 safeEqualSecret 先做 SHA-256 哈希再比较,而不是直接用 timingSafeEqual

    提示:考虑两个字符串长度不等的情况。

  2. SSRF 防护中,为什么要做 DNS 钉住(Pinned Lookup)?仅做 DNS 解析后检查 IP 不够吗?

    提示:考虑 DNS 解析和实际 TCP 连接之间的时间窗口。

  3. 命令执行审批系统为什么需要混淆检测?白名单匹配不是已经够安全了吗?

    提示:考虑 bash -c "$(echo 'cm0gLXJmIC8=' | base64 -d)" 这样的命令。

  4. DM 配对策略中,群组命令授权为什么不继承配对存储的批准?

    提示:考虑配对是针对 DM 个人的信任,群组是不同的安全边界。

![模块关系与设计模式总结:依赖层次与八大设计模式](https://qn.huat.xyz/blog/article-Illustration/OpenClaw 源码解读(十二)安全系统/12-infographic-design-patterns-1775150776731.png)


📌 小结: OpenClaw 的安全系统体现了纵深防御的理念——从网络层(SSRF 防护、TLS 强制)到应用层(认证授权、命令审批)再到数据层(密钥管理、配置脱敏),每一层都有独立的安全机制。这种设计确保了即使某一层被突破,攻击者仍然面对多重防线。阅读这些安全代码不仅能理解 OpenClaw 的工程实践,更能学习到通用的安全开发方法论。

读文档、看源码、写代码,理解 AI Agent 本质 🤖