Cline 的看板服务器:一条通往远程代码执行的跨源 WebSocket 劫持路径
2026 年 5 月的一份披露显示,Cline 看板的本地 WebSocket 服务器不校验任何来源——开发者访问的任何网站都能读取工作区并向正在运行的智能体注入命令。
这是什么?
2026 年 5 月 8 日,一份 GitHub 安全公告披露了随编码智能体 Cline 一同分发的看板(Kanban)中存在的跨源 WebSocket 劫持缺陷。由 cline 命令行启动的 npm 包 kanban 会在 127.0.0.1:3484 上开启一个本地 WebSocket 服务器,且在接受任何入站连接时既不校验 Origin 头,也不要求任何令牌。NVD 于 2026 年 6 月 1 日发布了该条目并评为严重(CVSS 9.6);CISA 的 ADP 富化信息于 6 月 3 日将其标记为具备概念验证(PoC)可利用性,技术影响为完全。截至公告发布时尚无修复版本——直至并包括 Cline 2.13.0 的所有版本均受影响。
手法是旧的,目标是新的。跨站 WebSocket 劫持(CSWSH)多年来一直收录于 OWASP 的知识体系中。改变的是套接字背后是什么:一个拥有实时终端和完整文件系统上下文的自主编码智能体,可从任意浏览器标签页触达。
工作原理
浏览器对 fetch 和 XMLHttpRequest 强制执行同源策略,但 WebSocket 的升级(upgrade)请求不受 CORS 约束。位于 https://any-site.example 的页面可以打开 ws://127.0.0.1:3484/...,浏览器会完成握手。唯一能阻止它的,是服务器在升级时校验 Origin 头——而 Cline 的看板服务器并未这样做。
三个端点在既无来源校验又无身份认证的情况下被暴露。一个运行时状态套接字会在客户端连接的瞬间推送完整的工作区快照:文件系统路径、git 分支、任务标题与描述,以及智能体的实时聊天消息。一个终端 I/O 套接字会将原始字节直接写入智能体的伪终端。一个控制套接字可以停止正在运行的任务。从概念上讲,存在漏洞的升级处理器大致如下:
server.on("upgrade", (request, socket, head) => {
// 检查了路径,但从不校验 Origin 头,
// 因此跨源页面也能完成握手。
runtimeStateHub.handleUpgrade(request, socket, head, { ... });
});
由此形成的链条是:从恶意页面发起连接并读取被推送的工作区快照;监听标记智能体正在运行的 task_sessions_updated 事件;然后向终端套接字发送以回车符结尾的文本。智能体会把注入的文本当作用户输入,而 \r 会像开发者按下回车一样将其提交——从而把文本注入转化为对命令 [REDACTED shell command] 的执行。除了开着看板并访问了错误的页面之外,无需任何用户交互。
示例提示
下面的代码片段说明了劫持为何奏效:本地服务器在完成 WebSocket 握手时未校验 Origin 头,因此任意标签页中的网页都能连接它。载荷已做删节——此示例仅供防御方参考。
# Cross-Site WebSocket Hijack on a local agent server (illustrative, defensive)
# A page the developer visits opens a socket the browser never blocks:
ws = connect("ws://127.0.0.1:3484/[terminal-endpoint]")
# Injected text + a carriage return would submit as agent input:
ws.send("[hidden instruction]\r") # [payload redacted]
# Root cause: the server accepts the upgrade without checking Origin.
# Defense: validate the Origin header on every WebSocket upgrade,
# require a per-session token, and bind to a random loopback port.
为什么重要
这是一个随着智能体走向桌面而不断重演的模式的具体实例:一个强大的本地服务,绑定在回环地址上,仅因为”只有 localhost 能访问它”就被视为可信。面对用户本就在运行的浏览器,回环地址并不是安全边界。任何广告框架、被污染的依赖或恶意链接都可以托管这段 JavaScript。仅就机密性而言——仓库路径、未发布的分支名、任务提示词,以及智能体自身的对话——对处理私有代码的开发者来说就已是严重泄露,而终端注入这一步会将其升级为在 macOS、Linux 和 Windows 上同样成立的远程代码执行。
防御
该公告的修复建议可推广到任何本地智能体服务器:
- 在每一次 WebSocket 升级时校验
Origin头。 拒绝一切并非智能体自身界面来源的连接。这是能封堵整类问题的单一修复。 - 要求一个不可猜测的会话令牌。 在服务器启动时生成一个随机密钥,在页面加载时交给合法界面,并将其作为连接参数强制校验。跨源页面无法猜到它。
- 对敏感套接字单独进行认证。 终端 I/O 与任务控制通道应验证调用方身份,而不是假定 localhost 即等于可信。
- 在可行时将服务绑定到随机高位端口和/或 unix 域套接字,且切勿在连接时以未经请求的快照推送任何机密。
- 作为用户,在你尚未用上修复版本之前: 在浏览不可信站点时避免运行看板,并把任何 localhost 上的智能体界面都当作可从互联网触达来对待。
状态
| 项目 | 值 |
|---|---|
| 参考编号 | CVE-2026-44211 / GHSA-5c57-rqjx-35g2 |
| 类别 | CSWSH(CWE-1385)+ 缺失身份认证(CWE-306) |
| 受影响 | Cline <= 2.13.0(npm 包 kanban) |
| CVSS 3.1 | 9.6 严重(AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H) |
| 披露 | GitHub 公告 2026-05-08;NVD 2026-06-01 |
| 补丁 | 披露时无可用补丁 |
| 利用情况 | 公开 PoC(CISA SSVC:技术影响为完全) |
关键日期:2026 年 5 月 5 日——CVE 预留。2026 年 5 月 8 日——GitHub 公告发布。2026 年 6 月 1 日——NVD 条目。2026 年 6 月 3 日——CISA ADP 富化。