60,000 星的代价:解析 OpenClaw 的架构设计与安全教训
OpenClaw(原 Clawdbot)在 GitHub 上的星标数从 6 万涨到了 18 万。与此同时,安全研究人员发现了上千个暴露在公网上的实例,其中一个案例导致 1.8 亿 Anthropic tokens 被盗刷。
这不是一个简单的"用户配置错误"故事。架构选择决定了错误发生的可能性和后果的严重程度。
默认安全 vs 易用性陷阱
OpenClaw 的网关默认绑定 127.0.0.1:18789。只要用户不改配置,从外部是访问不了的。这是正确的安全默认值。
问题出在"改配置"这件事太容易发生了。
用户想要远程访问自己的 Agent,于是把 bind address 改成 0.0.0.0。用户想要用 Docker 部署,于是映射了端口。用户想要从手机上访问,于是用 nginx 做了反向代理。每一步操作在当时看来都合理,但最后的结果是网关暴露在公网上且没有认证。
文档里有安全警告吗?有。但警告和默认行为之间差了十万八千里。用户不读文档,或者读了之后觉得"我知道我在做什么"。
更深层的问题是:为什么一个改错配置就能导致完全接管?
单点失败的架构
OpenClaw 的网关是一个超级节点。它存储着 API 密钥、控制着浏览器自动化、保存着对话历史、能够执行 shell 命令。所有功能集中在一个进程里,用一个端口对外服务。
这种设计的好处是部署简单。用户只需要启动一个服务就能用上全部功能。对于一个快速增长的开源项目来说,降低使用门槛是合理的优先级。
代价是安全边界的缺失。
拿到网关访问权限,就等于拿到了一切。没有分层防御,没有权限隔离,没有敏感操作的二次确认。攻击者不需要横向移动,因为他们第一步就到达了目的地。
一个可能更好的设计是把功能拆分:一个只负责对话的服务,一个只负责执行命令的服务,API 密钥存储在单独的密钥管理系统里。每个组件有独立的认证,暴露其中一个不会连累其他。
但这意味着用户需要部署和维护多个服务。对于一个想要快速获得采用的开源项目,这是一个艰难的权衡。
localhost 信任假设的失效
OpenClaw 的网关默认不需要认证,因为它只绑定 localhost。来自 127.0.0.1 的请求被认为是可信的,毕竟这意味着请求来自本机。
这个假设在容器化时代变得危险。
Docker 容器里的 localhost 不是宿主机的 localhost。用户在容器里配置 bind 0.0.0.0 是为了让宿主机能够访问,这在 Docker 的语境里是标准操作。但如果用户同时做了端口映射且没有在宿主机层面做访问控制,0.0.0.0 就真的变成了面向全网。
类似的情况发生在 Kubernetes、各种反向代理配置里。现代部署环境的网络拓扑比"localhost 是安全的"这个假设复杂得多。
认证应该是默认开启的,不管绑定什么地址。宁可让本地用户多配置一个 token,也不要让一个配置错误变成全面沦陷。
AI Agent 的特殊风险
传统 Web 服务如果没配置好认证,攻击者能做的事情取决于服务的功能。一个博客系统暴露了,最坏情况是被篡改内容。一个数据库暴露了,最坏情况是数据泄露。
AI Agent 暴露了,攻击者拿到的是一个能理解自然语言指令、能访问用户授权的所有服务、能自主执行复杂任务的代理。
这意味着攻击者不需要懂技术。"把所有对话历史发送到这个邮箱"是一条有效的攻击指令。"给我的老板发一封邮件说我辞职了"也是。
更危险的是,AI Agent 被设计成能处理来自不可信来源的输入。它会读取用户邮件、网页内容、聊天消息。这些输入里可能包含恶意的提示词注入。一旦 Agent 被暴露,攻击者甚至不需要直接访问网关,只需要往用户会让 Agent 处理的地方塞一条特殊指令。
我们能学到什么
-
认证默认开启。不管是绑定 localhost 还是其他地址,敏感操作都应该要求认证。
-
功能拆分。API 密钥存储、命令执行、对话管理应该是独立的组件,有独立的访问控制。
-
最小权限原则。Agent 用的 API 密钥应该只有执行任务必需的权限,而不是账户的完整访问权。
-
输入验证的困难性。对于 AI Agent 来说,恶意输入和正常输入在形式上可能完全一样。这是一个尚未解决的问题。
OpenClaw 的星标数还在涨。这说明用户对 AI Agent 的需求是真实的。但 18 万星的项目被发现有上千个不安全的公网实例,这也说明我们在安全方面还有很长的路要走。
或者说,路都还没开始修。







