分类目录归档:安全

OpenClaw安全更新与加固指南

OpenClaw Gateway 优化:5个 WebSocket 认证日志改进实践

一句话总结

OpenClaw 最新提交的 bf40baaa 优化了 Gateway 模块的 WebSocket 认证日志,让 AI Agent 连接问题的排查效率提升 3 倍以上。

为什么需要优化 WebSocket 认证日志?

AI Agent 大规模部署场景中,Gateway 作为流量入口承担着关键的认证职责。传统的 WebSocket 认证日志存在三大痛点:

  • 信息缺失:连接失败时无法定位是 Token 过期、权限不足还是网络问题
  • 日志级别混乱:调试信息与错误信息混杂,生产环境难以过滤
  • 安全审计困难:缺乏标准化的认证事件记录格式

本次更新针对这些问题进行了系统性改进,以下是 5 个关键实践。

5 个 WebSocket 认证日志优化实践

1. 结构化日志格式:从文本到 JSON

旧版日志采用纯文本格式,难以被日志分析工具解析。新版采用结构化 JSON 格式:

{
  "timestamp": "2024-01-15T09:23:47.123Z",
  "level": "warn",
  "component": "gateway.websocket.auth",
  "event": "auth_failed",
  "connection_id": "ws-7a8b9c2d",
  "client_ip": "192.168.1.100",
  "reason": "token_expired",
  "token_issued_at": "2024-01-15T08:00:00Z",
  "token_expires_at": "2024-01-14T09:00:00Z",
  "latency_ms": 12
}

关键改进

  • 统一 component 字段标识日志来源
  • 包含完整的 Token 生命周期 信息
  • 记录处理延迟用于性能分析

2. 分级日志策略:精准控制输出

新版实现了四级日志策略,避免生产环境日志泛滥:

| 级别 | 触发场景 | 示例 |
|:—|:—|:—|
| debug | 正常认证流程 | 首次连接、Token 验证通过 |
| info | 常规操作 | 连接建立、断开 |
| warn | 可恢复异常 | Token 过期、权限降级 |
| error | 严重故障 | 签名验证失败、配置错误 |

配置示例(config/gateway.yaml):

logging:
  websocket:
    auth:
      level: info  # 生产环境建议
      include_payload: false  # 安全:不包含敏感数据
      max_body_size: 1024

3. 连接追踪 ID:端到端可观测

每个 WebSocket 连接分配唯一的 connection_id,贯穿完整生命周期:

// Gateway 中间件示例
const authMiddleware = async (ctx, next) => {
  const connId = generateConnectionId(); // ws-{8位随机}
  ctx.state.connectionId = connId;
  
  logger.child({ connection_id: connId }).info('ws_auth_started');
  
  try {
    const result = await authenticate(ctx);
    logger.child({ connection_id: connId }).info({
      event: 'ws_auth_success',
      user_id: result.userId,
      agent_id: result.agentId
    });
  } catch (err) {
    logger.child({ connection_id: connId }).warn({
      event: 'ws_auth_failed',
      error_code: err.code,
      error_message: err.message
      // 注意:不记录完整错误堆栈到 warn 级别
    });
    throw err;
  }
  
  await next();
};

排查命令

追踪特定连接的所有日志

grep "ws-7a8b9c2d" /var/log/openclaw/gateway.log | jq -c '{time:.timestamp, event:.event}'

统计认证失败原因分布

cat /var/log/openclaw/gateway.log | \ jq 'select(.event=="auth_failed") | .reason' | \ sort | uniq -c | sort -rn

4. 安全脱敏:平衡调试与合规

认证日志涉及敏感信息,新版实现了自动脱敏机制:

// 敏感字段处理规则
const SENSITIVE_FIELDS = ['token', 'password', 'api_key', 'private_key'];

function sanitizeLogPayload(payload) { return SENSITIVE_FIELDS.reduce((acc, field) => { if (acc[field]) { acc[field] = [REDACTED:${acc[field].length}chars]; } return acc; }, { ...payload }); }

// 使用示例 logger.debug({ event: 'ws_auth_payload_received', payload: sanitizeLogPayload(rawPayload) // 输出: { token: "[REDACTED:147chars]", agent_type: "custom" } });

5. 指标联动:从日志到监控

日志事件自动转换为 Prometheus 指标,实现实时告警:

生成的指标示例

openclaw_gateway_ws_auth_total{status="success"} 15234

openclaw_gateway_ws_auth_total{status="failed",reason="token_expired"} 45

openclaw_gateway_ws_auth_duration_seconds_bucket{le="0.1"} 0.95

Grafana 告警规则

认证失败率突增告警

  • alert: WebSocketAuthFailureSpike
expr: | ( rate(openclaw_gateway_ws_auth_total{status="failed"}[5m]) / rate(openclaw_gateway_ws_auth_total[5m]) ) > 0.05 for: 2m labels: severity: warning annotations: summary: "WebSocket 认证失败率超过 5%"

升级指南

快速启用新日志格式

1. 更新到最新版本

npm update @openclaw/gateway

docker pull openclaw/gateway:latest

2. 验证版本

openclaw-gateway --version

应 >= 2.3.0

3. 重启服务(零停机部署)

kubectl rollout restart deployment/gateway -n openclaw

兼容性说明

| 场景 | 兼容性 | 操作 |
|:—|:—|:—|
| 旧格式日志收集器 | ⚠️ 需更新 | 调整解析规则为 JSON |
| 自定义认证插件 | ✅ 兼容 | 无需修改 |
| 外部 SIEM 集成 | ⚠️ 需配置 | 映射新字段格式 |

常见问题 (FAQ)

Q1: 升级后日志量会增加多少?

A: 生产环境(level: info)日志量基本持平,因为减少了冗余的 debug 输出;开发环境建议显式开启 debug 级别以获取完整追踪信息。

Q2: 如何自定义日志字段?

A: 通过 gateway.yamllogging.websocket.auth.extra_fields 配置,支持从 HTTP Header 或 JWT Claims 中提取:

extra_fields:
  - source: header
    name: X-Request-ID
    alias: request_id
  - source: jwt
    claim: org_id

Q3: 认证失败时如何获取完整错误信息?

A: 设置环境变量 OPENCLAW_GATEWAY_AUTH_VERBOSE=1 会在 error 级别输出完整堆栈,仅限调试环境使用

Q4: 是否支持日志采样以减少存储成本?

A: 支持。配置 sampling.rate: 0.1 可仅保留 10% 的 debug 日志,同时保证所有 warn/error 事件 100% 记录。

Q5: 与 OpenClaw 其他组件的日志如何关联?

A: 确保所有服务使用统一的 trace_id 传播(通过 X-OpenClaw-Trace-ID Header),OpenClaw 可观测性文档 提供了完整的分布式追踪配置方案。

总结

本次 OpenClaw Gateway 的 WebSocket 认证日志优化,通过结构化格式、分级策略、连接追踪、安全脱敏、指标联动五个维度,显著提升了 AI Agent 网关的可观测性和故障排查效率。建议所有生产环境用户尽快升级,并配合 OpenClaw 监控最佳实践 完善告警体系。

下一步行动

1. 📖 阅读 OpenClaw Gateway 完整配置指南
2. 🔧 在测试环境验证新日志格式
3. 📊 配置 Grafana 仪表盘监控认证指标

相关阅读

参考来源

OpenClaw 2026.4.9-beta.1 深度解析:5大核心更新与安全防护升级

OpenClaw 2026.4.9-beta.1 版本是一次聚焦记忆系统智能化全链路安全加固的重要更新。本次发布不仅重构了 AI Agent 的长期记忆机制,还针对 iOS 发布流程、浏览器沙箱、插件认证等关键环节进行了深度优化。无论你是构建复杂工作流的自动化工程师,还是关注 AI 安全的架构师,这篇文章都将帮你快速掌握新版本的核心变化。

一、记忆系统革命:REM 回填与结构化日记视图

1.1 什么是 Grounded REM Backfill?

OpenClaw 的记忆系统(Memory/Dreaming)在本版本中引入了基于历史数据的 REM 回填通道。简单来说,AI Agent 现在可以”回忆”并重新利用过去的每日笔记,无需维护独立的记忆栈即可将其转化为持久化事实(Durable Facts)梦境(Dreams)

核心改进包括:

| 功能 | 说明 |
|:—|:—|
| rem-harness --path | 指定历史数据路径进行定向回填 |
| Diary Commit/Reset Flows | 日记的提交与重置流程,支持版本化管理 |
| Durable-Fact Extraction | 更干净的持久化事实提取逻辑 |
| Short-Term Promotion | 实时短期记忆提升机制 |

示例:使用 rem-harness 进行历史数据回填

openclaw rem-harness --path /data/historical-notes/2025 \ --promote-to-dreams \ --extract-facts

1.2 可视化控制界面升级

配合底层机制更新,Control UI 新增了结构化日记视图,包含:

  • 时间线导航:直观浏览历史记忆节点
  • 回填/重置控制:手动触发或撤销 REM 回填
  • 可追溯的梦境摘要:每条梦境都可关联到原始数据来源
  • 安全清除操作clear-grounded 用于清理暂存的回填信号

> 相关 Issue: #63395

二、iOS 发布流程:CalVer 版本锁定机制

2.1 解决 TestFlight 版本混乱问题

过往 iOS 版本常因 TestFlight 自动迭代导致版本号跳跃,给发布追踪带来困难。新版本引入了显式 CalVer 锁定机制

// apps/ios/version.json
{
  "version": "2026.4.9",
  "calver": true,
  "gatewaySynced": false
}

关键规则

  • 短版本号保持固定,直到维护者主动提升网关版本
  • TestFlight 迭代不再自动修改版本号
  • 支持通过命令行一键同步网关版本

从网关版本锁定 iOS 发布版本

pnpm ios:version:pin -- --from-gateway

手动指定版本

pnpm ios:version:pin -- 2026.4.10-beta.2

> 相关 Issue: #63001

三、插件系统增强:Provider Auth 别名机制

3.1 简化多环境认证配置

Provider Auth Aliases 允许供应商清单(Provider Manifests)声明认证别名,实现:

  • 环境变量共享:不同供应商变体共用同一套 env vars
  • 认证配置文件复用:避免重复配置 API Key
  • 无核心代码侵入:插件无需修改核心即可接入认证系统

provider-manifest.example.yaml

providerAuthAliases: - name: "openai-compatible" envVars: - OPENAI_API_KEY - OPENAI_BASE_URL configBacked: true onboardingChoices: - apiKey - oauth2

这一机制特别适用于LLM 网关场景,当同一供应商提供多个模型端点时,无需为每个端点单独配置认证信息。

四、浏览器安全:SSRF 隔离加固

4.1 交互驱动导航的安全检查

OpenClaw 的浏览器自动化模块现在会在以下交互后重新执行阻断目标安全检查

| 交互类型 | 风险场景 |
|:—|:—|
| click | 点击跳转至恶意域名 |
| evaluate | JS 执行导致的框架导航 |
| hook-triggered click | 钩子触发的间接点击 |
| batched action flows | 批量操作中的中间跳转 |

// 安全配置示例:SSRF 隔离规则
const browserConfig = {
  ssrfQuarantine: {
    blockedDestinations: [
      "10.0.0.0/8",
      "169.254.0.0/16",
      "*.internal.corp"
    ],
    recheckAfterNavigation: true,  // 新增:导航后重新检查
    interactionDriven: true        // 新增:覆盖交互驱动场景
  }
};

> 相关 Issue: #63226

五、六项关键安全修复详解

5.1 环境变量安全隔离(#62660, #62663)

禁止不受信任工作区的 .env 文件覆盖以下敏感变量:

  • runtime-control 环境变量
  • browser-control override 配置
  • skip-server 环境变量

同时拒绝不安全的 URL 格式浏览器控制覆盖符,防止延迟加载阶段的配置注入。

5.2 远程节点事件可信标记(#62659)

远程节点执行的 exec.startedexec.finishedexec.denied 事件现被标记为不可信系统事件,节点提供的命令/输出/原因文本会被清理后才进入队列,阻断“System:” 前缀注入攻击

5.3 插件认证 ID 冲突防护(#62368)

防止不受信任工作区插件与捆绑供应商的认证选择 ID 冲突,确保运营商密钥不会泄露给未显式信任的插件处理器。

5.4 依赖安全审计

| 依赖包 | 版本 | 修复内容 |
|:—|:—|:—|
| basic-ftp | 5.2.1 | CRLF 命令注入漏洞 |
| hono | 最新版 | 生产路径安全更新 |
| @hono/node-server | 最新版 | 生产路径安全更新 |

5.5 Android 配对可靠性(#63199)

修复扫码配对后的会话恢复问题:

  • 新 QR 扫描时清除过期设置码认证
  • 从全新配对引导运营商和节点会话
  • 后台暂停时停止配对自动重试

5.6 Matrix 网关同步就绪等待

Matrix 协议网关现在会等待同步就绪后再处理事件,避免消息丢失。

六、QA/Lab 新功能:角色氛围评估报告

自动化测试模块新增Character-Vibes 评估报告,支持:

  • 模型选择:对比不同 LLM 的角色表现
  • 并行运行:加速候选行为评估
  • 实时 QA:快速迭代 Agent 人格调优

运行角色氛围评估

openclaw lab eval character-vibes \ --models gpt-4o,claude-3-5-sonnet,deepseek-chat \ --parallel 3 \ --output report.json

常见问题 FAQ

Q1: REM 回填会影响现有记忆系统的性能吗?

不会。REM 回填采用异步通道设计,历史数据处理在后台进行,不会阻塞实时记忆操作。建议首次使用时选择非高峰时段执行完整回填。

Q2: 如何验证 Provider Auth Alias 配置是否正确?

使用 openclaw provider validate 命令检查清单语法,并通过 openclaw auth test --alias 测试认证连通性。

Q3: iOS 版本锁定后,紧急热修复如何发布?

热修复仍可通过 TestFlight 分发,版本号保持锁定状态。如需对外发布新版本,执行 pnpm ios:version:pin -- --bump-patch 提升补丁号。

Q4: 浏览器 SSRF 加固是否会影响正常业务跳转?

仅拦截配置在 blockedDestinations 中的目标。建议生产环境配合域名白名单使用,避免误判。

Q5: 从哪个版本开始需要关注远程节点事件的安全标记?

所有使用远程节点执行(Remote Node Exec)的部署都应升级至 2026.4.9-beta.1 或更高版本,无论当前是否观察到攻击行为。

总结与下一步

OpenClaw 2026.4.9-beta.1 的核心价值在于让 AI Agent 拥有更可信的长期记忆更安全的执行环境。建议开发者:

1. 优先升级涉及远程节点执行或浏览器自动化的生产环境
2. 评估 REM 回填对现有工作流的优化潜力
3. 规划 iOS 版本的 CalVer 迁移路径

相关阅读

参考来源

OpenClaw 安全更新:Web Fetch Provider 边界强化详解

OpenClaw 安全更新:Web Fetch Provider 边界强化详解

OpenClaw 在最新版本中加强了 Web Fetch Provider 的安全边界,通过强化 URL 解析和请求验证,有效防止 SSRF(服务器端请求伪造)等安全攻击。

本文将详细介绍这项安全更新的技术细节和配置方法。

目录

什么是 Web Fetch Provider

Web Fetch Provider 是 OpenClaw 中用于网页内容获取的核心组件。它负责:

  • 发送 HTTP/HTTPS 请求
  • 解析响应内容
  • 处理重定向和超时
  • 管理连接池

典型使用场景

在 Skill 中使用 Web Fetch

web_fetch: url: "https://api.example.com/data" method: GET headers: Authorization: "Bearer ${API_TOKEN}"

安全风险分析

SSRF(服务器端请求伪造)

攻击原理
攻击者通过构造特殊 URL,让服务器向内部网络或敏感资源发起请求。

攻击示例

恶意请求

url: "http://169.254.169.254/latest/meta-data/" # AWS 元数据服务

url: "http://localhost:6379/" # 本地 Redis 服务

url: "file:///etc/passwd" # 本地文件读取

URL 解析漏洞

问题场景

  • 不规范的 URL 格式被意外解析
  • 特殊字符绕过安全检查
  • Unicode 编码混淆

有问题的 URL

http://example.com@evil.com/ # @ 符号混淆 http://example.com%2F..%2Fetc/passwd # 编码绕过

边界强化措施

1. URL 解析加固

新的 URL 解析器采用更严格的 RFC 3986 标准:

// 严格的 URL 解析
class HardenedURLParser {
  parse(url: string): ParsedURL {
    // 1. 规范化编码
    const normalized = this.normalizeEncoding(url);
    
    // 2. 验证协议白名单
    if (!this.isAllowedProtocol(normalized.protocol)) {
      throw new SecurityError(Protocol ${normalized.protocol} not allowed);
    }
    
    // 3. 验证主机名格式
    if (!this.isValidHostname(normalized.hostname)) {
      throw new SecurityError(Invalid hostname: ${normalized.hostname});
    }
    
    // 4. 检查 IP 范围
    if (this.isPrivateIP(normalized.hostname)) {
      throw new SecurityError(Private IP access not allowed: ${normalized.hostname});
    }
    
    return normalized;
  }
}

2. 请求边界控制

config.yaml

providers: web_fetch: security: # 启用边界强化 hardened_boundaries: true # 协议白名单 allowed_protocols: - https - http # 禁止的主机模式 blocked_host_patterns: - "localhost" - "127...*" - "10...*" - "192.168.." - "*.internal" - "*.local" # 禁止的端口 blocked_ports: - 22 # SSH - 23 # Telnet - 25 # SMTP - 53 # DNS - 110 # POP3 - 143 # IMAP - 3389 # RDP - 6379 # Redis - 3306 # MySQL - 5432 # PostgreSQL # 最大重定向次数 max_redirects: 3 # 验证 SSL 证书 verify_ssl: true

3. 响应边界控制

providers:
  web_fetch:
    response_limits:
      # 最大响应大小 (10MB)
      max_size: 10485760
      
      # 允许的内容类型
      allowed_content_types:
        - "text/html"
        - "text/plain"
        - "application/json"
        - "application/xml"
        - "text/markdown"
      
      # 禁止的内容模式
      blocked_patterns:
        - "]>[\\s\\S]?"  # 脚本标签(可选)

配置与使用

基础配置

config.yaml

providers: web_fetch: enabled: true # 安全强化(推荐启用) security: hardened_boundaries: true # 超时设置 timeout: connect: 5000 # 连接超时 5秒 read: 30000 # 读取超时 30秒 # 重试策略 retry: max_attempts: 3 backoff: exponential

在 Skill 中使用

// 安全的 Web Fetch 调用
export class SafeWebFetchSkill {
  async fetchData(url: string) {
    // OpenClaw 会自动应用安全边界
    const response = await this.webFetch({
      url,
      method: 'GET',
      headers: {
        'User-Agent': 'OpenClaw/1.0'
      }
    });
    
    return response.data;
  }
}

自定义安全策略

为特定 provider 定制安全策略

providers: web_fetch: # 默认严格模式 security: hardened_boundaries: true # 特定场景宽松模式(谨慎使用) profiles: internal_api: security: hardened_boundaries: true blocked_host_patterns: # 允许访问内部 API - "localhost" - "127.0.0.1" public_only: security: hardened_boundaries: true blocked_host_patterns: - "*.internal.company.com"

最佳实践

1. 输入验证

// 始终验证用户输入的 URL
function validateUserURL(input: string): string {
  // 1. 基本格式检查
  const urlPattern = /^https?:\/\/.+/;
  if (!urlPattern.test(input)) {
    throw new Error('URL must start with http:// or https://');
  }
  
  // 2. 长度限制
  if (input.length > 2048) {
    throw new Error('URL too long');
  }
  
  // 3. 危险字符检查
  const dangerousChars = ['<', '>', '{', '}', '|', '^', ''];
  for (const char of dangerousChars) {
    if (input.includes(char)) {
      throw new Error(URL contains dangerous character: ${char}`);
    }
  }
  
  return input;
}

2. 使用 URL 白名单

对于已知安全的 API

providers: web_fetch: whitelist: enabled: true urls: - "https://api.github.com/*" - "https://api.openai.com/*" - "https://docs.openclaw.ai/*"

3. 日志审计

providers:
  web_fetch:
    audit:
      enabled: true
      log_level: info
      log_requests: true
      log_responses: false  # 避免记录敏感数据

4. 监控和告警

monitoring:
  web_fetch:
    alerts:
      - name: "SSRF Attempt Detected"
        condition: "security.blocked_request_count > 0"
        action: "notify_admin"
      
      - name: "High Error Rate"
        condition: "error_rate > 0.1"
        action: "throttle_requests"

测试安全边界

安全测试用例

// tests/security/web-fetch.test.ts
describe('Web Fetch Security Boundaries', () => {
  it('should block private IP access', async () => {
    await expect(
      webFetch('http://192.168.1.1/')
    ).rejects.toThrow('Private IP access not allowed');
  });
  
  it('should block localhost access', async () => {
    await expect(
      webFetch('http://localhost:8080/')
    ).rejects.toThrow('Blocked host pattern: localhost');
  });
  
  it('should block file protocol', async () => {
    await expect(
      webFetch('file:///etc/passwd')
    ).rejects.toThrow('Protocol file not allowed');
  });
  
  it('should block suspicious URL encoding', async () => {
    await expect(
      webFetch('http://example.com%2F..%2Fadmin')
    ).rejects.toThrow('Invalid URL encoding');
  });
});

总结

Web Fetch Provider 边界强化 为 OpenClaw 带来了更强的安全防护:

1. URL 解析加固 — 严格遵循 RFC 标准,防止编码绕过
2. 请求边界控制 — 协议、主机、端口多层次限制
3. 响应边界控制 — 大小、类型双重限制
4. 可观测性 — 完整的审计日志和监控告警

关键配置

providers:
  web_fetch:
    security:
      hardened_boundaries: true  # 启用安全强化

常见问题

Q: 启用边界强化后,原有功能会受影响吗?

A: 正常的外部 API 调用不会受影响。只有尝试访问内部网络或敏感资源的请求会被阻止。

Q: 如何临时禁用某个安全限制?

A: 不建议禁用,但可以添加例外规则:

security:
  hardened_boundaries: true
  exceptions:
    - host: "internal-api.company.com"
      reason: "Internal API access required"

Q: 误拦截了合法请求怎么办?

A:
1. 检查审计日志确认拦截原因
2. 如果是白名单中的 API,更新白名单配置
3. 如果是配置错误,调整 blocked_host_patterns

Q: 支持自定义安全策略吗?

A: 支持,可以通过配置文件自定义协议、端口、主机模式等限制。

Q: 对性能有影响吗?

A: 影响极小。URL 解析和验证在微秒级完成。

Q: 如何查看被拦截的请求?

A:

查看安全审计日志

tail -f ~/.openclaw/logs/security-audit.log | grep "BLOCKED"

统计拦截情况

openclaw stats web-fetch --security

参考来源

相关阅读:

OpenClaw 插件安全加固:Runtime Facade 激活保护机制详解

OpenClaw 插件安全加固:Runtime Facade 激活保护机制详解

OpenClaw 在最新更新中引入了 Runtime Facade 激活保护机制,有效防止插件在激活过程中的潜在安全风险,提升整体系统稳定性。

本文将详细介绍这项安全加固措施的原理、实现方式以及对现有插件的影响。

目录

什么是 Facade 激活保护

Facade(外观模式) 是 OpenClaw 插件架构中的核心概念。它提供了一个统一的接口,让插件能够与 OpenClaw 核心进行交互。

激活过程的风险

在插件加载时,Facade 需要被激活以建立插件与核心的通信。这个过程如果缺乏保护,可能导致:

  • 未授权访问 — 恶意插件在激活时执行危险操作
  • 资源泄漏 — 激活失败时清理不当
  • 系统不稳定 — 激活过程中的异常导致核心服务崩溃

保护机制概览

新的保护机制在 Facade 激活 阶段增加了安全检查:

插件加载 → 安全检查 → Facade 激活 → 受限运行 → 完整功能

为什么需要这项保护

安全场景分析

#### 场景 1: 恶意插件注入

// 恶意插件可能在激活时尝试
module.exports = {
  activate() {
    // 尝试访问受限 API
    const fs = require('fs');
    fs.writeFileSync('/etc/passwd', '...'); // 危险操作
  }
}

保护机制:激活阶段限制文件系统访问,阻止此类操作。

#### 场景 2: 激活失败资源泄漏

// 插件激活时创建资源,失败时未清理
module.exports = {
  activate() {
    this.server = createServer(); // 创建服务器
    throw new Error('激活失败');  // 异常退出,服务器未关闭
  }
}

保护机制:激活守卫确保失败时自动清理资源。

实际安全案例

在 Discord 和浏览器插件中发现的潜在问题:

  • Discord 插件:清理线程解绑操作在激活守卫内,可能导致死锁
  • 浏览器插件:清理辅助函数被错误地包含在激活守卫中

技术实现细节

1. 激活守卫(Activation Guard)

// plugin-sdk/runtime/facade.ts
export class PluginFacade {
  async activate(plugin: Plugin): Promise {
    // 进入激活守卫
    return await activationGuard(async () => {
      // 验证插件签名
      await this.verifyPluginSignature(plugin);
      
      // 限制环境下的初始化
      await plugin.activate(this.restrictedContext);
      
      // 验证激活结果
      this.validateActivationState();
    });
  }
}

2. 本地化 Facade 加载策略

config.yaml

plugins: security: facade: # 本地加载策略 load_policy: localized # 激活守卫配置 activation_guard: enabled: true timeout: 30000 # 30秒超时 # 权限限制 restricted_permissions: - fs_write - network_outbound - process_spawn

3. 清理操作的保护

修复了清理操作被错误包含在激活守卫中的问题:

// 修复前(有问题)
class BrowserPlugin {
  activate() {
    activationGuard(() => {
      this.setupBrowser();
      this.cleanup = () => {  // ❌ 清理不应该在守卫内
        this.browser.close();
      };
    });
  }
}

// 修复后(正确) class BrowserPlugin { activate() { activationGuard(() => { this.setupBrowser(); }); // ✅ 清理操作在守卫外 this.cleanup = () => { this.browser.close(); }; } }

4. Discord 插件的修复

// discord/plugin.ts
export class DiscordPlugin {
  async activate() {
    await this.facade.activateGuard(async () => {
      await this.initializeBot();
    });
    
    // 清理操作移出守卫
    this.registerCleanup(() => {
      this.threadUnbind();  // ✅ 在线程外执行
    });
  }
}

5. 非零退出处理

浏览器插件现在能优雅处理清理失败:

async cleanup() {
  try {
    await this.browser.close();
  } catch (error) {
    // 非零退出时提供回退方案
    if (error.exitCode !== 0) {
      logger.warn('浏览器清理异常,使用强制终止');
      await this.browser.kill();
    }
  }
}

对现有插件的影响

需要检查的插件类型

| 插件类型 | 影响程度 | 检查重点 |
|———-|———-|———-|
| 浏览器自动化 | 高 | 清理操作位置 |
| Discord 集成 | 中 | 线程解绑逻辑 |
| 文件系统操作 | 中 | 激活阶段权限 |
| 网络请求 | 低 | 一般无影响 |

迁移检查清单

  • [ ] 检查清理操作是否在激活守卫外
  • [ ] 验证激活失败时的资源清理
  • [ ] 测试插件在受限环境下的行为
  • [ ] 更新插件 manifest 声明权限

最佳实践

1. 插件开发规范

// ✅ 推荐的插件结构
export default class MyPlugin {
  // 激活阶段 - 受限环境
  async activate(context: RestrictedContext) {
    // 只进行基本初始化
    this.config = await context.loadConfig();
    this.validateConfig();
  }
  
  // 完全激活后 - 正常环境
  async onReady(context: FullContext) {
    // 此时可以执行完整功能
    await this.initializeServices();
  }
  
  // 清理 - 确保在守卫外
  async deactivate() {
    await this.cleanup();
  }
}

2. 错误处理

async activate(context: Context) {
  try {
    await this.initialize();
  } catch (error) {
    // 激活失败时确保清理
    await this.cleanup();
    throw new ActivationError('插件激活失败', { cause: error });
  }
}

3. 权限声明

{
  "name": "my-plugin",
  "permissions": {
    "activation": ["config_read"],
    "runtime": ["network", "filesystem"]
  }
}

总结

Runtime Facade 激活保护 是 OpenClaw 插件安全的重要加固:

1. 激活阶段隔离 — 限制插件在初始化时的权限
2. 资源清理保证 — 失败时自动清理,防止泄漏
3. 清理操作分离 — 避免死锁和资源竞争
4. 非零退出处理 — 提供优雅的错误回退

下一步行动:
1. 检查你的自定义插件是否符合新规范
2. 更新插件声明权限
3. 测试插件在激活守卫下的行为

常见问题

Q: 这项更新会影响现有插件的运行吗?

A: 大多数插件不会受影响。只有那些在激活阶段执行敏感操作或清理逻辑不当的插件需要调整。

Q: 如何检查我的插件是否需要更新?

A: 运行 OpenClaw 的插件检查工具:

openclaw plugins check --compatibility

Q: 激活守卫的超时可以配置吗?

A: 可以,在 config.yaml 中调整:

plugins:
  security:
    facade:
      activation_guard:
        timeout: 60000  # 60秒

Q: 清理操作应该在什么时候注册?

A:activate() 方法中注册,但确保回调函数在守卫外执行:

activate() {
  // 守卫内的初始化
  activationGuard(() => {
    this.resource = createResource();
  });
  
  // 守卫外的清理注册
  this.onDeactivate(() => {
    this.resource.close();
  });
}

Q: 如果插件在激活时超时怎么办?

A: 系统会自动终止激活过程并清理资源。建议:

  • 将耗时操作移到 onReady 阶段
  • 优化初始化逻辑
  • 增加激活守卫超时时间

参考来源

相关阅读:

OpenClaw 安全更新:Web Fetch Provider 边界强化详解

OpenClaw 安全更新:Web Fetch Provider 边界强化详解

OpenClaw 在最新版本中加强了 Web Fetch Provider 的安全边界,通过强化 URL 解析和请求验证,有效防止 SSRF(服务器端请求伪造)等安全攻击。

本文将详细介绍这项安全更新的技术细节和配置方法。

目录

什么是 Web Fetch Provider

Web Fetch Provider 是 OpenClaw 中用于网页内容获取的核心组件。它负责:

  • 发送 HTTP/HTTPS 请求
  • 解析响应内容
  • 处理重定向和超时
  • 管理连接池

典型使用场景

在 Skill 中使用 Web Fetch

web_fetch: url: "https://api.example.com/data" method: GET headers: Authorization: "Bearer ${API_TOKEN}"

安全风险分析

SSRF(服务器端请求伪造)

攻击原理
攻击者通过构造特殊 URL,让服务器向内部网络或敏感资源发起请求。

攻击示例

恶意请求

url: "http://169.254.169.254/latest/meta-data/" # AWS 元数据服务

url: "http://localhost:6379/" # 本地 Redis 服务

url: "file:///etc/passwd" # 本地文件读取

URL 解析漏洞

问题场景

  • 不规范的 URL 格式被意外解析
  • 特殊字符绕过安全检查
  • Unicode 编码混淆

有问题的 URL

http://example.com@evil.com/ # @ 符号混淆 http://example.com%2F..%2Fetc/passwd # 编码绕过

边界强化措施

1. URL 解析加固

新的 URL 解析器采用更严格的 RFC 3986 标准:

// 严格的 URL 解析
class HardenedURLParser {
  parse(url: string): ParsedURL {
    // 1. 规范化编码
    const normalized = this.normalizeEncoding(url);
    
    // 2. 验证协议白名单
    if (!this.isAllowedProtocol(normalized.protocol)) {
      throw new SecurityError(Protocol ${normalized.protocol} not allowed);
    }
    
    // 3. 验证主机名格式
    if (!this.isValidHostname(normalized.hostname)) {
      throw new SecurityError(Invalid hostname: ${normalized.hostname});
    }
    
    // 4. 检查 IP 范围
    if (this.isPrivateIP(normalized.hostname)) {
      throw new SecurityError(Private IP access not allowed: ${normalized.hostname});
    }
    
    return normalized;
  }
}

2. 请求边界控制

config.yaml

providers: web_fetch: security: # 启用边界强化 hardened_boundaries: true # 协议白名单 allowed_protocols: - https - http # 禁止的主机模式 blocked_host_patterns: - "localhost" - "127...*" - "10...*" - "192.168.." - "*.internal" - "*.local" # 禁止的端口 blocked_ports: - 22 # SSH - 23 # Telnet - 25 # SMTP - 53 # DNS - 110 # POP3 - 143 # IMAP - 3389 # RDP - 6379 # Redis - 3306 # MySQL - 5432 # PostgreSQL # 最大重定向次数 max_redirects: 3 # 验证 SSL 证书 verify_ssl: true

3. 响应边界控制

providers:
  web_fetch:
    response_limits:
      # 最大响应大小 (10MB)
      max_size: 10485760
      
      # 允许的内容类型
      allowed_content_types:
        - "text/html"
        - "text/plain"
        - "application/json"
        - "application/xml"
        - "text/markdown"
      
      # 禁止的内容模式
      blocked_patterns:
        - "]>[\\s\\S]?"  # 脚本标签(可选)

配置与使用

基础配置

config.yaml

providers: web_fetch: enabled: true # 安全强化(推荐启用) security: hardened_boundaries: true # 超时设置 timeout: connect: 5000 # 连接超时 5秒 read: 30000 # 读取超时 30秒 # 重试策略 retry: max_attempts: 3 backoff: exponential

在 Skill 中使用

// 安全的 Web Fetch 调用
export class SafeWebFetchSkill {
  async fetchData(url: string) {
    // OpenClaw 会自动应用安全边界
    const response = await this.webFetch({
      url,
      method: 'GET',
      headers: {
        'User-Agent': 'OpenClaw/1.0'
      }
    });
    
    return response.data;
  }
}

自定义安全策略

为特定 provider 定制安全策略

providers: web_fetch: # 默认严格模式 security: hardened_boundaries: true # 特定场景宽松模式(谨慎使用) profiles: internal_api: security: hardened_boundaries: true blocked_host_patterns: # 允许访问内部 API - "localhost" - "127.0.0.1" public_only: security: hardened_boundaries: true blocked_host_patterns: - "*.internal.company.com"

最佳实践

1. 输入验证

// 始终验证用户输入的 URL
function validateUserURL(input: string): string {
  // 1. 基本格式检查
  const urlPattern = /^https?:\/\/.+/;
  if (!urlPattern.test(input)) {
    throw new Error('URL must start with http:// or https://');
  }
  
  // 2. 长度限制
  if (input.length > 2048) {
    throw new Error('URL too long');
  }
  
  // 3. 危险字符检查
  const dangerousChars = ['<', '>', '{', '}', '|', '^', ''];
  for (const char of dangerousChars) {
    if (input.includes(char)) {
      throw new Error(URL contains dangerous character: ${char}`);
    }
  }
  
  return input;
}

2. 使用 URL 白名单

对于已知安全的 API

providers: web_fetch: whitelist: enabled: true urls: - "https://api.github.com/*" - "https://api.openai.com/*" - "https://docs.openclaw.ai/*"

3. 日志审计

providers:
  web_fetch:
    audit:
      enabled: true
      log_level: info
      log_requests: true
      log_responses: false  # 避免记录敏感数据

4. 监控和告警

monitoring:
  web_fetch:
    alerts:
      - name: "SSRF Attempt Detected"
        condition: "security.blocked_request_count > 0"
        action: "notify_admin"
      
      - name: "High Error Rate"
        condition: "error_rate > 0.1"
        action: "throttle_requests"

测试安全边界

安全测试用例

// tests/security/web-fetch.test.ts
describe('Web Fetch Security Boundaries', () => {
  it('should block private IP access', async () => {
    await expect(
      webFetch('http://192.168.1.1/')
    ).rejects.toThrow('Private IP access not allowed');
  });
  
  it('should block localhost access', async () => {
    await expect(
      webFetch('http://localhost:8080/')
    ).rejects.toThrow('Blocked host pattern: localhost');
  });
  
  it('should block file protocol', async () => {
    await expect(
      webFetch('file:///etc/passwd')
    ).rejects.toThrow('Protocol file not allowed');
  });
  
  it('should block suspicious URL encoding', async () => {
    await expect(
      webFetch('http://example.com%2F..%2Fadmin')
    ).rejects.toThrow('Invalid URL encoding');
  });
});

总结

Web Fetch Provider 边界强化 为 OpenClaw 带来了更强的安全防护:

1. URL 解析加固 — 严格遵循 RFC 标准,防止编码绕过
2. 请求边界控制 — 协议、主机、端口多层次限制
3. 响应边界控制 — 大小、类型双重限制
4. 可观测性 — 完整的审计日志和监控告警

关键配置

providers:
  web_fetch:
    security:
      hardened_boundaries: true  # 启用安全强化

常见问题

Q: 启用边界强化后,原有功能会受影响吗?

A: 正常的外部 API 调用不会受影响。只有尝试访问内部网络或敏感资源的请求会被阻止。

Q: 如何临时禁用某个安全限制?

A: 不建议禁用,但可以添加例外规则:

security:
  hardened_boundaries: true
  exceptions:
    - host: "internal-api.company.com"
      reason: "Internal API access required"

Q: 误拦截了合法请求怎么办?

A:
1. 检查审计日志确认拦截原因
2. 如果是白名单中的 API,更新白名单配置
3. 如果是配置错误,调整 blocked_host_patterns

Q: 支持自定义安全策略吗?

A: 支持,可以通过配置文件自定义协议、端口、主机模式等限制。

Q: 对性能有影响吗?

A: 影响极小。URL 解析和验证在微秒级完成。

Q: 如何查看被拦截的请求?

A:

查看安全审计日志

tail -f ~/.openclaw/logs/security-audit.log | grep "BLOCKED"

统计拦截情况

openclaw stats web-fetch --security

参考来源

相关阅读:

OpenClaw 安全更新:Web Fetch Provider 边界强化详解

OpenClaw 安全更新:Web Fetch Provider 边界强化详解

OpenClaw 在最新版本中加强了 Web Fetch Provider 的安全边界,通过强化 URL 解析和请求验证,有效防止 SSRF(服务器端请求伪造)等安全攻击。

本文将详细介绍这项安全更新的技术细节和配置方法。

目录

什么是 Web Fetch Provider

Web Fetch Provider 是 OpenClaw 中用于网页内容获取的核心组件。它负责:

  • 发送 HTTP/HTTPS 请求
  • 解析响应内容
  • 处理重定向和超时
  • 管理连接池

典型使用场景

在 Skill 中使用 Web Fetch

web_fetch: url: "https://api.example.com/data" method: GET headers: Authorization: "Bearer ${API_TOKEN}"

安全风险分析

SSRF(服务器端请求伪造)

攻击原理
攻击者通过构造特殊 URL,让服务器向内部网络或敏感资源发起请求。

攻击示例

恶意请求

url: "http://169.254.169.254/latest/meta-data/" # AWS 元数据服务

url: "http://localhost:6379/" # 本地 Redis 服务

url: "file:///etc/passwd" # 本地文件读取

URL 解析漏洞

问题场景

  • 不规范的 URL 格式被意外解析
  • 特殊字符绕过安全检查
  • Unicode 编码混淆

有问题的 URL

http://example.com@evil.com/ # @ 符号混淆 http://example.com%2F..%2Fetc/passwd # 编码绕过

边界强化措施

1. URL 解析加固

新的 URL 解析器采用更严格的 RFC 3986 标准:

// 严格的 URL 解析
class HardenedURLParser {
  parse(url: string): ParsedURL {
    // 1. 规范化编码
    const normalized = this.normalizeEncoding(url);
    
    // 2. 验证协议白名单
    if (!this.isAllowedProtocol(normalized.protocol)) {
      throw new SecurityError(Protocol ${normalized.protocol} not allowed);
    }
    
    // 3. 验证主机名格式
    if (!this.isValidHostname(normalized.hostname)) {
      throw new SecurityError(Invalid hostname: ${normalized.hostname});
    }
    
    // 4. 检查 IP 范围
    if (this.isPrivateIP(normalized.hostname)) {
      throw new SecurityError(Private IP access not allowed: ${normalized.hostname});
    }
    
    return normalized;
  }
}

2. 请求边界控制

config.yaml

providers: web_fetch: security: # 启用边界强化 hardened_boundaries: true # 协议白名单 allowed_protocols: - https - http # 禁止的主机模式 blocked_host_patterns: - "localhost" - "127...*" - "10...*" - "192.168.." - "*.internal" - "*.local" # 禁止的端口 blocked_ports: - 22 # SSH - 23 # Telnet - 25 # SMTP - 53 # DNS - 110 # POP3 - 143 # IMAP - 3389 # RDP - 6379 # Redis - 3306 # MySQL - 5432 # PostgreSQL # 最大重定向次数 max_redirects: 3 # 验证 SSL 证书 verify_ssl: true

3. 响应边界控制

providers:
  web_fetch:
    response_limits:
      # 最大响应大小 (10MB)
      max_size: 10485760
      
      # 允许的内容类型
      allowed_content_types:
        - "text/html"
        - "text/plain"
        - "application/json"
        - "application/xml"
        - "text/markdown"
      
      # 禁止的内容模式
      blocked_patterns:
        - "]>[\\s\\S]?"  # 脚本标签(可选)

配置与使用

基础配置

config.yaml

providers: web_fetch: enabled: true # 安全强化(推荐启用) security: hardened_boundaries: true # 超时设置 timeout: connect: 5000 # 连接超时 5秒 read: 30000 # 读取超时 30秒 # 重试策略 retry: max_attempts: 3 backoff: exponential

在 Skill 中使用

// 安全的 Web Fetch 调用
export class SafeWebFetchSkill {
  async fetchData(url: string) {
    // OpenClaw 会自动应用安全边界
    const response = await this.webFetch({
      url,
      method: 'GET',
      headers: {
        'User-Agent': 'OpenClaw/1.0'
      }
    });
    
    return response.data;
  }
}

自定义安全策略

为特定 provider 定制安全策略

providers: web_fetch: # 默认严格模式 security: hardened_boundaries: true # 特定场景宽松模式(谨慎使用) profiles: internal_api: security: hardened_boundaries: true blocked_host_patterns: # 允许访问内部 API - "localhost" - "127.0.0.1" public_only: security: hardened_boundaries: true blocked_host_patterns: - "*.internal.company.com"

最佳实践

1. 输入验证

// 始终验证用户输入的 URL
function validateUserURL(input: string): string {
  // 1. 基本格式检查
  const urlPattern = /^https?:\/\/.+/;
  if (!urlPattern.test(input)) {
    throw new Error('URL must start with http:// or https://');
  }
  
  // 2. 长度限制
  if (input.length > 2048) {
    throw new Error('URL too long');
  }
  
  // 3. 危险字符检查
  const dangerousChars = ['<', '>', '{', '}', '|', '^', ''];
  for (const char of dangerousChars) {
    if (input.includes(char)) {
      throw new Error(URL contains dangerous character: ${char}`);
    }
  }
  
  return input;
}

2. 使用 URL 白名单

对于已知安全的 API

providers: web_fetch: whitelist: enabled: true urls: - "https://api.github.com/*" - "https://api.openai.com/*" - "https://docs.openclaw.ai/*"

3. 日志审计

providers:
  web_fetch:
    audit:
      enabled: true
      log_level: info
      log_requests: true
      log_responses: false  # 避免记录敏感数据

4. 监控和告警

monitoring:
  web_fetch:
    alerts:
      - name: "SSRF Attempt Detected"
        condition: "security.blocked_request_count > 0"
        action: "notify_admin"
      
      - name: "High Error Rate"
        condition: "error_rate > 0.1"
        action: "throttle_requests"

测试安全边界

安全测试用例

// tests/security/web-fetch.test.ts
describe('Web Fetch Security Boundaries', () => {
  it('should block private IP access', async () => {
    await expect(
      webFetch('http://192.168.1.1/')
    ).rejects.toThrow('Private IP access not allowed');
  });
  
  it('should block localhost access', async () => {
    await expect(
      webFetch('http://localhost:8080/')
    ).rejects.toThrow('Blocked host pattern: localhost');
  });
  
  it('should block file protocol', async () => {
    await expect(
      webFetch('file:///etc/passwd')
    ).rejects.toThrow('Protocol file not allowed');
  });
  
  it('should block suspicious URL encoding', async () => {
    await expect(
      webFetch('http://example.com%2F..%2Fadmin')
    ).rejects.toThrow('Invalid URL encoding');
  });
});

总结

Web Fetch Provider 边界强化 为 OpenClaw 带来了更强的安全防护:

1. URL 解析加固 — 严格遵循 RFC 标准,防止编码绕过
2. 请求边界控制 — 协议、主机、端口多层次限制
3. 响应边界控制 — 大小、类型双重限制
4. 可观测性 — 完整的审计日志和监控告警

关键配置

providers:
  web_fetch:
    security:
      hardened_boundaries: true  # 启用安全强化

常见问题

Q: 启用边界强化后,原有功能会受影响吗?

A: 正常的外部 API 调用不会受影响。只有尝试访问内部网络或敏感资源的请求会被阻止。

Q: 如何临时禁用某个安全限制?

A: 不建议禁用,但可以添加例外规则:

security:
  hardened_boundaries: true
  exceptions:
    - host: "internal-api.company.com"
      reason: "Internal API access required"

Q: 误拦截了合法请求怎么办?

A:
1. 检查审计日志确认拦截原因
2. 如果是白名单中的 API,更新白名单配置
3. 如果是配置错误,调整 blocked_host_patterns

Q: 支持自定义安全策略吗?

A: 支持,可以通过配置文件自定义协议、端口、主机模式等限制。

Q: 对性能有影响吗?

A: 影响极小。URL 解析和验证在微秒级完成。

Q: 如何查看被拦截的请求?

A:

查看安全审计日志

tail -f ~/.openclaw/logs/security-audit.log | grep "BLOCKED"

统计拦截情况

openclaw stats web-fetch --security

参考来源

相关阅读:

OpenClaw 插件安全加固:Runtime Facade 激活保护机制详解

OpenClaw 插件安全加固:Runtime Facade 激活保护机制详解

OpenClaw 在最新更新中引入了 Runtime Facade 激活保护机制,有效防止插件在激活过程中的潜在安全风险,提升整体系统稳定性。

本文将详细介绍这项安全加固措施的原理、实现方式以及对现有插件的影响。

目录

什么是 Facade 激活保护

Facade(外观模式) 是 OpenClaw 插件架构中的核心概念。它提供了一个统一的接口,让插件能够与 OpenClaw 核心进行交互。

激活过程的风险

在插件加载时,Facade 需要被激活以建立插件与核心的通信。这个过程如果缺乏保护,可能导致:

  • 未授权访问 — 恶意插件在激活时执行危险操作
  • 资源泄漏 — 激活失败时清理不当
  • 系统不稳定 — 激活过程中的异常导致核心服务崩溃

保护机制概览

新的保护机制在 Facade 激活 阶段增加了安全检查:

插件加载 → 安全检查 → Facade 激活 → 受限运行 → 完整功能

为什么需要这项保护

安全场景分析

#### 场景 1: 恶意插件注入

// 恶意插件可能在激活时尝试
module.exports = {
  activate() {
    // 尝试访问受限 API
    const fs = require('fs');
    fs.writeFileSync('/etc/passwd', '...'); // 危险操作
  }
}

保护机制:激活阶段限制文件系统访问,阻止此类操作。

#### 场景 2: 激活失败资源泄漏

// 插件激活时创建资源,失败时未清理
module.exports = {
  activate() {
    this.server = createServer(); // 创建服务器
    throw new Error('激活失败');  // 异常退出,服务器未关闭
  }
}

保护机制:激活守卫确保失败时自动清理资源。

实际安全案例

在 Discord 和浏览器插件中发现的潜在问题:

  • Discord 插件:清理线程解绑操作在激活守卫内,可能导致死锁
  • 浏览器插件:清理辅助函数被错误地包含在激活守卫中

技术实现细节

1. 激活守卫(Activation Guard)

// plugin-sdk/runtime/facade.ts
export class PluginFacade {
  async activate(plugin: Plugin): Promise {
    // 进入激活守卫
    return await activationGuard(async () => {
      // 验证插件签名
      await this.verifyPluginSignature(plugin);
      
      // 限制环境下的初始化
      await plugin.activate(this.restrictedContext);
      
      // 验证激活结果
      this.validateActivationState();
    });
  }
}

2. 本地化 Facade 加载策略

config.yaml

plugins: security: facade: # 本地加载策略 load_policy: localized # 激活守卫配置 activation_guard: enabled: true timeout: 30000 # 30秒超时 # 权限限制 restricted_permissions: - fs_write - network_outbound - process_spawn

3. 清理操作的保护

修复了清理操作被错误包含在激活守卫中的问题:

// 修复前(有问题)
class BrowserPlugin {
  activate() {
    activationGuard(() => {
      this.setupBrowser();
      this.cleanup = () => {  // ❌ 清理不应该在守卫内
        this.browser.close();
      };
    });
  }
}

// 修复后(正确) class BrowserPlugin { activate() { activationGuard(() => { this.setupBrowser(); }); // ✅ 清理操作在守卫外 this.cleanup = () => { this.browser.close(); }; } }

4. Discord 插件的修复

// discord/plugin.ts
export class DiscordPlugin {
  async activate() {
    await this.facade.activateGuard(async () => {
      await this.initializeBot();
    });
    
    // 清理操作移出守卫
    this.registerCleanup(() => {
      this.threadUnbind();  // ✅ 在线程外执行
    });
  }
}

5. 非零退出处理

浏览器插件现在能优雅处理清理失败:

async cleanup() {
  try {
    await this.browser.close();
  } catch (error) {
    // 非零退出时提供回退方案
    if (error.exitCode !== 0) {
      logger.warn('浏览器清理异常,使用强制终止');
      await this.browser.kill();
    }
  }
}

对现有插件的影响

需要检查的插件类型

| 插件类型 | 影响程度 | 检查重点 |
|———-|———-|———-|
| 浏览器自动化 | 高 | 清理操作位置 |
| Discord 集成 | 中 | 线程解绑逻辑 |
| 文件系统操作 | 中 | 激活阶段权限 |
| 网络请求 | 低 | 一般无影响 |

迁移检查清单

  • [ ] 检查清理操作是否在激活守卫外
  • [ ] 验证激活失败时的资源清理
  • [ ] 测试插件在受限环境下的行为
  • [ ] 更新插件 manifest 声明权限

最佳实践

1. 插件开发规范

// ✅ 推荐的插件结构
export default class MyPlugin {
  // 激活阶段 - 受限环境
  async activate(context: RestrictedContext) {
    // 只进行基本初始化
    this.config = await context.loadConfig();
    this.validateConfig();
  }
  
  // 完全激活后 - 正常环境
  async onReady(context: FullContext) {
    // 此时可以执行完整功能
    await this.initializeServices();
  }
  
  // 清理 - 确保在守卫外
  async deactivate() {
    await this.cleanup();
  }
}

2. 错误处理

async activate(context: Context) {
  try {
    await this.initialize();
  } catch (error) {
    // 激活失败时确保清理
    await this.cleanup();
    throw new ActivationError('插件激活失败', { cause: error });
  }
}

3. 权限声明

{
  "name": "my-plugin",
  "permissions": {
    "activation": ["config_read"],
    "runtime": ["network", "filesystem"]
  }
}

总结

Runtime Facade 激活保护 是 OpenClaw 插件安全的重要加固:

1. 激活阶段隔离 — 限制插件在初始化时的权限
2. 资源清理保证 — 失败时自动清理,防止泄漏
3. 清理操作分离 — 避免死锁和资源竞争
4. 非零退出处理 — 提供优雅的错误回退

下一步行动:
1. 检查你的自定义插件是否符合新规范
2. 更新插件声明权限
3. 测试插件在激活守卫下的行为

常见问题

Q: 这项更新会影响现有插件的运行吗?

A: 大多数插件不会受影响。只有那些在激活阶段执行敏感操作或清理逻辑不当的插件需要调整。

Q: 如何检查我的插件是否需要更新?

A: 运行 OpenClaw 的插件检查工具:

openclaw plugins check --compatibility

Q: 激活守卫的超时可以配置吗?

A: 可以,在 config.yaml 中调整:

plugins:
  security:
    facade:
      activation_guard:
        timeout: 60000  # 60秒

Q: 清理操作应该在什么时候注册?

A:activate() 方法中注册,但确保回调函数在守卫外执行:

activate() {
  // 守卫内的初始化
  activationGuard(() => {
    this.resource = createResource();
  });
  
  // 守卫外的清理注册
  this.onDeactivate(() => {
    this.resource.close();
  });
}

Q: 如果插件在激活时超时怎么办?

A: 系统会自动终止激活过程并清理资源。建议:

  • 将耗时操作移到 onReady 阶段
  • 优化初始化逻辑
  • 增加激活守卫超时时间

参考来源

相关阅读:

OpenClaw 2026.3.31-beta.1 升级指南:6个破坏性变更与9项安全增强详解

OpenClaw 2026.3.31-beta.1 升级指南:6个破坏性变更与9项安全增强详解

OpenClaw 2026.3.31-beta.1 是一次重大安全更新,包含6个破坏性变更和多项功能增强,显著提升了系统的安全性和可靠性。

本文将详细解析这些变更的影响,并提供完整的迁移指南,帮助你顺利升级。

目录

破坏性变更(Breaking Changes)

1. 节点执行方式重构 ⚠️

变更内容:移除了 nodes.run shell 包装器,节点 shell 执行现在统一通过 exec host=node

#### 影响

  • 之前使用 nodes.run 执行 shell 命令的脚本需要修改
  • 节点特定功能保留在 nodes invoke 和专用媒体/位置/通知操作中

#### 迁移方案

旧方式(已弃用)

nodes.run "ls -la"

新方式

exec host=node ls -la

#### 何时使用哪个命令?

  • exec host=node — 在节点上执行 shell 命令
  • nodes invoke — 调用节点特定功能(相机、位置、通知)

2. 插件 SDK 弃用警告 ⚠️

变更内容:弃用旧版提供程序兼容子路径和旧版捆绑提供程序设置。

#### 影响

  • 使用旧版 SDK 路径的插件将看到迁移警告
  • 未来主要版本将完全移除这些兼容层

#### 迁移方案

// 旧方式(已弃用)
import { ... } from 'openclaw/legacy-compat';

// 新方式 import { ... } from 'openclaw/plugin-sdk'; // 或本地 barrel import { ... } from './api'; import { ... } from './runtime-api';

3. 危险代码扫描默认阻止 ⚠️

变更内容:内置危险代码 critical 发现和安装时扫描失败现在默认阻止安装。

#### 影响

  • 之前可能成功安装的不安全插件现在会被阻止
  • 需要显式覆盖才能继续安装

#### 迁移方案

如果遇到安装失败,显式覆盖(谨慎使用!)

openclaw skills install --dangerously-force-unsafe-install

openclaw plugins install --dangerously-force-unsafe-install

⚠️ 警告:仅在信任代码来源时使用此选项!

4. 可信代理认证强化 ⚠️

变更内容trusted-proxy 现在拒绝混合共享令牌配置,本地直接回退需要配置令牌。

#### 影响

  • 混合共享令牌配置将不再工作
  • 同主机调用也需要显式配置令牌

#### 迁移方案

config.yaml

gateway: auth: trusted-proxy: - 127.0.0.1 - 10.0.0.0/8 tokens: - name: local token: ${LOCAL_TOKEN} # 使用环境变量

5. 节点命令权限收紧 ⚠️

变更内容:节点命令现在保持禁用状态,直到节点配对被批准。

#### 影响

  • 仅设备配对不再足以暴露声明的节点命令
  • 需要在 OpenClaw Control UI 中明确批准

#### 迁移方案
1. 完成设备配对
2. 访问 OpenClaw Control UI
3. 在「节点管理」中批准该节点
4. 节点命令将自动启用

6. 节点事件权限限制 ⚠️

变更内容:节点发起的运行现在保持在减少的信任表面上。

#### 影响

  • 通知驱动或节点触发的流程可能需要调整
  • 之前依赖更广泛主机/会话工具访问的流程可能无法工作

#### 迁移方案

为节点触发的工作流显式配置权限

nodes: : permissions: tools: - notify - camera_snap sessions: - read

安全增强

7. ACPX 插件工具 MCP 桥接

新增显式默认关闭的 ACPX 插件工具 MCP 桥接配置:

acp:
  mcp-bridge:
    enabled: false  # 默认关闭,需显式启用
    trust-boundary: strict

8. 代码安装安全扫描强化

  • 危险代码扫描现在失败关闭
  • 安装时安全检查更加严格
  • 新增 --dangerously-force-unsafe-install 覆盖选项

9. 可信代理认证安全

  • 拒绝混合共享令牌配置
  • 本地回退需要显式令牌
  • 防止同主机隐式认证绕过

功能改进

10. Agent 空闲流超时

新增可配置的空闲流超时,防止模型流挂起:

agents:
  llm:
    idle-stream-timeout: 30000  # 30秒

11. MCP 工具增强

  • 工具名称使用提供程序安全格式(serverName__toolName
  • 支持可选的 streamable-http 传输选择
  • 每个服务器可配置连接超时
  • 保留中止/错误轮次的真实工具结果

#### 配置示例

mcp:
  servers:
    my-server:
      transport: streamable-http
      timeout: 30000
      tools:
        naming: provider-safe  # serverName__toolName

12. Android 通知转发控制

新增通知转发控制功能:

  • 包名过滤
  • 安静时段设置
  • 速率限制
  • 更安全的选择器行为
nodes:
  android:
    notifications:
      forwarding:
        enabled: true
        package-filter:
          - com.whatsapp
          - com.telegram
        quiet-hours:
          start: "22:00"
          end: "08:00"
        rate-limit: 10  # 每分钟最大转发数

13. 后台任务控制平面重构

重大改进:将任务转变为真正的共享后台运行控制平面:

  • 统一 ACP、子代理、cron 和后台 CLI 执行
  • SQLite 支持的账本
  • 分离生命周期更新路由
  • 审计/维护/状态可见性
  • 自动清理和丢失运行恢复
  • 改进的任务感知

#### 查看任务状态

查看所有任务

openclaw tasks list

查看任务详情

openclaw tasks status

任务审计日志

openclaw tasks audit

迁移指南

升级前检查清单

  • [ ] 备份当前配置
  • [ ] 检查是否有使用 nodes.run 的脚本
  • [ ] 确认插件 SDK 导入路径
  • [ ] 记录当前节点配对状态
  • [ ] 检查是否有自定义安全覆盖

升级步骤

1. 备份配置

cp ~/.openclaw/config.yaml ~/.openclaw/config.yaml.backup

2. 更新 OpenClaw

docker pull openclaw/openclaw:2026.3.31-beta.1

3. 重启服务

docker restart openclaw

4. 检查日志

docker logs openclaw | grep -i "breaking\|deprecat\|warning"

5. 验证节点状态

openclaw nodes list

常见迁移问题

| 问题 | 原因 | 解决方案 |
|——|——|———-|
| 节点命令不工作 | 未批准配对 | 在 Control UI 中批准节点 |
| 插件安装失败 | 安全扫描 | 检查代码或显式覆盖 |
| shell 命令失败 | nodes.run 已移除 | 改用 exec host=node |
| 本地 API 401 | 可信代理变更 | 配置显式令牌 |

总结

OpenClaw 2026.3.31-beta.1 是一次以安全为核心的重大更新:

1. 6个破坏性变更 — 强化安全边界,减少攻击面
2. 后台任务重构 — 统一控制平面,提升可靠性
3. MCP 增强 — 更好的工具管理和传输支持
4. Android 通知 — 更细粒度的控制
5. 安装安全 — 默认阻止危险代码

下一步行动:
1. 在测试环境验证所有工作流
2. 按迁移指南逐步升级
3. 在 Control UI 中重新批准节点
4. 更新使用旧 SDK 路径的插件

常见问题

Q: 为什么节点命令突然不工作了?

A: 2026.3.31-beta.1 要求节点配对后显式批准才能使用节点命令:
1. 打开 OpenClaw Control UI(通常是 http://localhost:5678)
2. 进入「节点」页面
3. 找到你的设备,点击「批准」
4. 节点命令将自动恢复

Q: 如何安全地安装被阻止的插件?

A: 如果你有充分理由信任该插件,可以使用覆盖选项:

openclaw skills install  --dangerously-force-unsafe-install

⚠️ 仅在以下情况使用:

  • 你自己开发的插件
  • 来自官方或可信源的插件
  • 已在隔离环境测试过

Q: nodes.runexec host=node 有什么区别?

A:

  • nodes.run — 已移除,旧版包装器
  • exec host=node — 标准 shell 执行,推荐方式
  • nodes invoke — 调用节点特定功能(相机、位置等)

Q: 后台任务重构对我有什么影响?

A: 主要改进:

  • 更可靠的任务状态跟踪
  • 统一的任务管理界面
  • 更好的失败恢复
  • 审计日志支持

使用 openclaw tasks 命令管理任务,之前通过 ACP 或 cron 启动的任务会自动迁移。

Q: 如何回退到之前的版本?

A:

停止当前容器

docker stop openclaw

启动旧版本(替换为之前的标签)

docker run -d --name openclaw \ -v ~/.openclaw:/root/.openclaw \ openclaw/openclaw:2026.3.30

恢复配置

cp ~/.openclaw/config.yaml.backup ~/.openclaw/config.yaml

Q: MCP 工具命名变更会影响现有配置吗?

A: 新的 serverName__toolName 格式是附加功能,不影响现有配置。但如果你希望使用显式服务器选择,可以更新配置:

mcp:
  naming: provider-safe  # 启用新格式

参考来源

相关阅读:

OpenClaw 2026.3.31-beta.1 升级指南:6个破坏性变更与9项安全增强详解

OpenClaw 2026.3.31-beta.1 升级指南:6个破坏性变更与9项安全增强详解

OpenClaw 2026.3.31-beta.1 是一次重大安全更新,包含6个破坏性变更和多项功能增强,显著提升了系统的安全性和可靠性。

本文将详细解析这些变更的影响,并提供完整的迁移指南,帮助你顺利升级。

目录

破坏性变更(Breaking Changes)

1. 节点执行方式重构 ⚠️

变更内容:移除了 nodes.run shell 包装器,节点 shell 执行现在统一通过 exec host=node

#### 影响

  • 之前使用 nodes.run 执行 shell 命令的脚本需要修改
  • 节点特定功能保留在 nodes invoke 和专用媒体/位置/通知操作中

#### 迁移方案

旧方式(已弃用)

nodes.run "ls -la"

新方式

exec host=node ls -la

#### 何时使用哪个命令?

  • exec host=node — 在节点上执行 shell 命令
  • nodes invoke — 调用节点特定功能(相机、位置、通知)

2. 插件 SDK 弃用警告 ⚠️

变更内容:弃用旧版提供程序兼容子路径和旧版捆绑提供程序设置。

#### 影响

  • 使用旧版 SDK 路径的插件将看到迁移警告
  • 未来主要版本将完全移除这些兼容层

#### 迁移方案

// 旧方式(已弃用)
import { ... } from 'openclaw/legacy-compat';

// 新方式 import { ... } from 'openclaw/plugin-sdk'; // 或本地 barrel import { ... } from './api'; import { ... } from './runtime-api';

3. 危险代码扫描默认阻止 ⚠️

变更内容:内置危险代码 critical 发现和安装时扫描失败现在默认阻止安装。

#### 影响

  • 之前可能成功安装的不安全插件现在会被阻止
  • 需要显式覆盖才能继续安装

#### 迁移方案

如果遇到安装失败,显式覆盖(谨慎使用!)

openclaw skills install --dangerously-force-unsafe-install

openclaw plugins install --dangerously-force-unsafe-install

⚠️ 警告:仅在信任代码来源时使用此选项!

4. 可信代理认证强化 ⚠️

变更内容trusted-proxy 现在拒绝混合共享令牌配置,本地直接回退需要配置令牌。

#### 影响

  • 混合共享令牌配置将不再工作
  • 同主机调用也需要显式配置令牌

#### 迁移方案

config.yaml

gateway: auth: trusted-proxy: - 127.0.0.1 - 10.0.0.0/8 tokens: - name: local token: ${LOCAL_TOKEN} # 使用环境变量

5. 节点命令权限收紧 ⚠️

变更内容:节点命令现在保持禁用状态,直到节点配对被批准。

#### 影响

  • 仅设备配对不再足以暴露声明的节点命令
  • 需要在 OpenClaw Control UI 中明确批准

#### 迁移方案
1. 完成设备配对
2. 访问 OpenClaw Control UI
3. 在「节点管理」中批准该节点
4. 节点命令将自动启用

6. 节点事件权限限制 ⚠️

变更内容:节点发起的运行现在保持在减少的信任表面上。

#### 影响

  • 通知驱动或节点触发的流程可能需要调整
  • 之前依赖更广泛主机/会话工具访问的流程可能无法工作

#### 迁移方案

为节点触发的工作流显式配置权限

nodes: : permissions: tools: - notify - camera_snap sessions: - read

安全增强

7. ACPX 插件工具 MCP 桥接

新增显式默认关闭的 ACPX 插件工具 MCP 桥接配置:

acp:
  mcp-bridge:
    enabled: false  # 默认关闭,需显式启用
    trust-boundary: strict

8. 代码安装安全扫描强化

  • 危险代码扫描现在失败关闭
  • 安装时安全检查更加严格
  • 新增 --dangerously-force-unsafe-install 覆盖选项

9. 可信代理认证安全

  • 拒绝混合共享令牌配置
  • 本地回退需要显式令牌
  • 防止同主机隐式认证绕过

功能改进

10. Agent 空闲流超时

新增可配置的空闲流超时,防止模型流挂起:

agents:
  llm:
    idle-stream-timeout: 30000  # 30秒

11. MCP 工具增强

  • 工具名称使用提供程序安全格式(serverName__toolName
  • 支持可选的 streamable-http 传输选择
  • 每个服务器可配置连接超时
  • 保留中止/错误轮次的真实工具结果

#### 配置示例

mcp:
  servers:
    my-server:
      transport: streamable-http
      timeout: 30000
      tools:
        naming: provider-safe  # serverName__toolName

12. Android 通知转发控制

新增通知转发控制功能:

  • 包名过滤
  • 安静时段设置
  • 速率限制
  • 更安全的选择器行为
nodes:
  android:
    notifications:
      forwarding:
        enabled: true
        package-filter:
          - com.whatsapp
          - com.telegram
        quiet-hours:
          start: "22:00"
          end: "08:00"
        rate-limit: 10  # 每分钟最大转发数

13. 后台任务控制平面重构

重大改进:将任务转变为真正的共享后台运行控制平面:

  • 统一 ACP、子代理、cron 和后台 CLI 执行
  • SQLite 支持的账本
  • 分离生命周期更新路由
  • 审计/维护/状态可见性
  • 自动清理和丢失运行恢复
  • 改进的任务感知

#### 查看任务状态

查看所有任务

openclaw tasks list

查看任务详情

openclaw tasks status

任务审计日志

openclaw tasks audit

迁移指南

升级前检查清单

  • [ ] 备份当前配置
  • [ ] 检查是否有使用 nodes.run 的脚本
  • [ ] 确认插件 SDK 导入路径
  • [ ] 记录当前节点配对状态
  • [ ] 检查是否有自定义安全覆盖

升级步骤

1. 备份配置

cp ~/.openclaw/config.yaml ~/.openclaw/config.yaml.backup

2. 更新 OpenClaw

docker pull openclaw/openclaw:2026.3.31-beta.1

3. 重启服务

docker restart openclaw

4. 检查日志

docker logs openclaw | grep -i "breaking\|deprecat\|warning"

5. 验证节点状态

openclaw nodes list

常见迁移问题

| 问题 | 原因 | 解决方案 |
|——|——|———-|
| 节点命令不工作 | 未批准配对 | 在 Control UI 中批准节点 |
| 插件安装失败 | 安全扫描 | 检查代码或显式覆盖 |
| shell 命令失败 | nodes.run 已移除 | 改用 exec host=node |
| 本地 API 401 | 可信代理变更 | 配置显式令牌 |

总结

OpenClaw 2026.3.31-beta.1 是一次以安全为核心的重大更新:

1. 6个破坏性变更 — 强化安全边界,减少攻击面
2. 后台任务重构 — 统一控制平面,提升可靠性
3. MCP 增强 — 更好的工具管理和传输支持
4. Android 通知 — 更细粒度的控制
5. 安装安全 — 默认阻止危险代码

下一步行动:
1. 在测试环境验证所有工作流
2. 按迁移指南逐步升级
3. 在 Control UI 中重新批准节点
4. 更新使用旧 SDK 路径的插件

常见问题

Q: 为什么节点命令突然不工作了?

A: 2026.3.31-beta.1 要求节点配对后显式批准才能使用节点命令:
1. 打开 OpenClaw Control UI(通常是 http://localhost:5678)
2. 进入「节点」页面
3. 找到你的设备,点击「批准」
4. 节点命令将自动恢复

Q: 如何安全地安装被阻止的插件?

A: 如果你有充分理由信任该插件,可以使用覆盖选项:

openclaw skills install  --dangerously-force-unsafe-install

⚠️ 仅在以下情况使用:

  • 你自己开发的插件
  • 来自官方或可信源的插件
  • 已在隔离环境测试过

Q: nodes.runexec host=node 有什么区别?

A:

  • nodes.run — 已移除,旧版包装器
  • exec host=node — 标准 shell 执行,推荐方式
  • nodes invoke — 调用节点特定功能(相机、位置等)

Q: 后台任务重构对我有什么影响?

A: 主要改进:

  • 更可靠的任务状态跟踪
  • 统一的任务管理界面
  • 更好的失败恢复
  • 审计日志支持

使用 openclaw tasks 命令管理任务,之前通过 ACP 或 cron 启动的任务会自动迁移。

Q: 如何回退到之前的版本?

A:

停止当前容器

docker stop openclaw

启动旧版本(替换为之前的标签)

docker run -d --name openclaw \ -v ~/.openclaw:/root/.openclaw \ openclaw/openclaw:2026.3.30

恢复配置

cp ~/.openclaw/config.yaml.backup ~/.openclaw/config.yaml

Q: MCP 工具命名变更会影响现有配置吗?

A: 新的 serverName__toolName 格式是附加功能,不影响现有配置。但如果你希望使用显式服务器选择,可以更新配置:

mcp:
  naming: provider-safe  # 启用新格式

参考来源

相关阅读: