作者注:拆解 Cursor 扩展市场恶意 Claude Code 插件事件。重点说明 66 行前置加载器如何触发、两组 SSH 密钥与反向隧道如何配合、哪些结论已证实哪些未证实,以及开发者该如何排查。
2026 年 10 月 29 日,Cursor 的 VS Code 扩展市场出现一个被篡改的 anthropic.claude-code 扩展。研究人员在它的 extension.js 开头发现了 一段约 66 行的 JavaScript 加载器。只要编辑器加载这个模块,它就会尝试在开发者电脑上植入持久化的 SSH 后门。
这不是小道消息。 Cursor 官方安全公告、Microsoft Security Research、Phorion、StepSecurity、OpenSourceMalware 和 Expel 都已发布分析,Expel 还调查了 4 起真实客户事件。截至 11 月 1 日,StepSecurity 补充了精确样本比对,技术全貌基本清晰。
核心价值:3 分钟理解这 66 行代码到底做了什么、为什么用户不需要执行任何危险命令,以及卸载插件之后为什么仍不能确认安全。

66 行 JavaScript 后门事件核心信息速览
先把事件边界说清楚。这是一起开发工具软件供应链攻击,问题出在 Cursor 的扩展分发渠道。Claude 模型本身没有被攻破,Anthropic 内部系统也没有被入侵的证据。微软已确认,Microsoft Visual Studio Marketplace 和官方 npm 包 @anthropic-ai/claude-code 均未受影响。
| 信息项 | 详情 |
|---|---|
| 发生日期 | 2026 年 10 月 29 日 |
| 分发渠道 | Cursor VS Code Extension Marketplace |
| 冒用身份 | anthropic.claude-code(Anthropic 并未构建或发布这些版本) |
| 恶意版本 | 2.1.312、2.1.313 |
| 官方列出的恶意安装包平台 | Windows x64、macOS ARM64 |
| 公开分发时长 | 约 11 小时 8 分钟 |
| 官方披露的受影响用户上限 | 5000 人(是上限,不等于 5000 台被控制) |
| 注入代码 | extension.js 第 1–66 行的前置加载器 |
| 后续修复版本 | Anthropic 发布 2.1.314 |
66 行 JavaScript 后门事件时间线
下面的时间均换算为北京时间。需要区分两个概念:一个是安装包可以下载的时间,另一个是已下载的安装包实际运行的时间,后者可能明显更晚。
| 北京时间 | 事件 |
|---|---|
| 10 月 29 日 17:27 | 恶意扩展开始在 Cursor 市场提供下载 |
| 10 月 30 日 04:35 | Cursor 停止分发,暴露窗口关闭 |
| 10 月 30 日 | Cursor 发布安全公告,Phorion、OpenSourceMalware、微软相继发布分析 |
| 10 月 30 日 12:45 | Expel 观察到一台客户 Mac 首次运行恶意代码,晚于下架约 8 小时 |
| 10 月 31 日 02:30 | Cursor 更新公告,将 2.1.312 列入受影响版本,并修订入侵指标 |
| 11 月 1 日 | StepSecurity 基于 MalwareBazaar 样本完成精确静态比对 |
事件曝光后,Cursor 移除了恶意版本,并临时关闭整个扩展市场,同时完成以下工作:审计访问记录、轮换密钥、重建市场,并协调云服务商关闭攻击者服务器。目前公开资料还没有解释攻击者如何获得向 Cursor 市场发布构建的权限。在调查结论出来之前,不应断言是 Anthropic 账户被盗或 Cursor 存在某个具体漏洞。
66 行 JavaScript 如何触发 Claude Code 插件后门
“66 行”很容易被误读成“整个插件只有 66 行”。实际情况是,正常的 extension.js 是一个体积很大的压缩文件。攻击者只在文件最前面插入了一段恶意加载器,它从第 1 行开始,到第 66 行结束。
这段代码使用立即执行函数表达式(IIFE)。它不需要等待用户向 Claude 发消息,也不需要任何触发条件。Cursor 用 Node.js 运行环境加载扩展主文件时,这段逻辑就会先于正常业务代码执行。
7,386 字节的改动:样本精确比对
StepSecurity 在 11 月 1 日从 MalwareBazaar 获取样本,核对 SHA-256 后做了静态比对。结果说明,攻击者完全没有必要重写插件。
| 对比项 | 数值 |
|---|---|
正常 extension.js |
3,685,536 字节 |
恶意 extension.js |
3,692,922 字节 |
| 新增加载器 | 7,386 字节 |
| 新增内容占比 | 约 0.20% |
| 外部清单版本号 | 2.1.313 |
| 业务代码内部自我标识 | 2.1.312 |
最后两行同样值得注意。攻击者以 2.1.312 的正常构建为基础重新打包,只修改了外部版本信息。显示的版本号与代码的真实来源并不一定一致,因此只凭版本号做判断并不可靠。StepSecurity 正文另一处“剩余字节数”的表述存在算术不一致,引用时应以上表的整体大小和增量为准。
为什么用户不需要执行任何危险命令
这次攻击和提示词注入没有关系。研究人员确认,整个过程具备以下特征:
- 不需要用户发起 Claude 对话,也不需要模型同意执行高危指令;
- 不依赖恶意 Prompt,也不依赖 npm 安装生命周期脚本;
- 初始攻击不需要下载额外的可执行文件。
真正的风险来自 IDE 扩展在开发者电脑上的执行权限。扩展跑在 Node.js 里,天然可以调用文件系统、读取系统信息、创建子进程、执行系统命令、发起 HTTP 请求,以及调用本机的 SSH 工具。

Claude Code 插件 SSH 后门的两组密钥设计
这段 66 行代码最巧妙的地方,是把后门完全建立在系统自带的 SSH 之上。攻击者不需要开发一套自定义远控程序,只需要两组用途不同的 SSH 身份配合即可。
第一组是受害电脑的授权密钥。 恶意程序向用户的 authorized_keys 追加攻击者公钥,公开的标记为 svc-telemetry。如果本机 SSH 服务处于开启状态,持有对应私钥的人就有机会以该用户身份登录。
第二组是连接外部服务器的身份密钥。 恶意程序另行保存一把私钥,让受害设备能主动连接攻击者服务器。这把密钥不是用户原有的私钥。简单来说,第一组解决“攻击者能否通过认证”,第二组解决“受害电脑能否先连出去”。
反向 SSH 隧道为什么值得警惕
很多企业和家庭网络会阻止公网直接访问个人电脑,但电脑主动向外发起连接通常不受限制。反向隧道正好利用了这一点:受害电脑先连上攻击者服务器,再把另一端的访问请求转回本地的 22 端口。
不过,连接存在不等于登录成功。能否最终登录,取决于本机 SSH 是否运行、认证配置是否生效,以及攻击者服务器的转发设置。如果本地 SSH 没有启动,隧道仍可能建立,但无法完成远程登录。
66 行恶意代码的隐蔽手法与实现缺陷
为了降低被发现的概率,加载器采取了几种措施:
- 正常的 Claude Code 功能继续加载;
- 各攻击步骤单独捕获异常,静默失败后继续执行;
- 持久化任务使用
SysMon、com.apple.sysmond等仿冒系统组件的名称; - 连接失败后约每 60 秒重试一次;
- 启动约 1.5 秒后尝试上报信息。
用户界面上可能看不到任何异常。
恶意代码本身也有明显缺陷,这在客观上降低了远程登录的成功率:
| 平台 | 实现缺陷 | 实际影响 |
|---|---|---|
| macOS | 以普通权限查询 Remote Login 状态,返回权限错误;代码只在识别到明确的“关闭”状态时才尝试开启 | 许多原本没开 SSH 的 Mac 不会被自动开启远程登录;若 SSH 原本已开启,风险仍在 |
| Windows | 用 PowerShell 安装 OpenSSH Server,却通过依赖 /bin/sh 的辅助函数执行 |
标准 Windows 没有该路径,SSH 服务启用步骤可能失败 |
| Linux | 通过 crontab @reboot 持久化,Phorion 发现 crontab 检查有缺陷 |
重复执行时可能误伤用户原有定时任务;Linux 实际分发规模未确认 |
缺陷不代表代码完全失效。写入用户自己的文件、创建用户级启动项,往往不需要管理员权限。因此可能出现这样一种情况:远程登录服务没能启动,但授权密钥已经写入,启动脚本已经生成,主机信息已经发出,后台进程也在持续尝试外连。“没有管理员权限就完全安全”的想法并不成立。
Claude Code 插件后门对开发者的影响分析
对开发者的影响
- API Key 相关的环境变量名称可能已经暴露:加载器最多筛选 40 个名称中包含
KEY、TOKEN、SECRET、PASS、AWS、GCP的环境变量。初始上报的是名称而非值,但攻击者可以据此判断你在用哪些 API 或云平台。一旦后门可用,本地凭证仍可能被进一步读取。 - 卸载插件不等于清除后门:持久化文件、启动项和 SSH 公钥不会随扩展卸载自动消失。Expel 的一起案例显示,用户在插件下架后才打开 Cursor,恶意活动随即开始,并持续了接近 10 小时。
- 单一指标会漏报:Expel 发现一台机器有恶意隧道进程,却没有
svc-telemetry公钥标记。排查时需要同时核对版本、文件哈希、进程、网络连接和启动项。
对行业的影响
- IDE 扩展成为高价值攻击面:AI 编程工具普及后,开发者电脑上同时存放着源码、云凭证和模型 API Key。在一个 3.6MB 的压缩文件前面插入 7KB 代码,就足以改变它的安全属性。
- 第三方扩展市场的发布链路需要重新审视:这次事件只发生在 Cursor 市场,而同名扩展在其他渠道没有问题。这说明“发布者名称看起来是官方”并不能作为信任依据。

上图由 API易 apiyi.com 技术团队根据公开研究整理。下表把事实边界单独列出,引用或转述时请注意区分:
| 结论 | 状态 | 说明 |
|---|---|---|
| Cursor 市场分发过被篡改的 Claude Code 扩展 | 已证实 | 官方公告确认 |
| 恶意代码具备信息收集、密钥植入、反向隧道、持久化能力 | 已证实 | 多家机构样本分析一致 |
| 存在真实客户设备上的恶意活动 | 已证实 | Expel 处理 4 起,均为 Mac |
| 5000 台电脑被完全控制 | 未证实 | 5000 只是可能受影响的上限 |
| 用户 API Key 实际值被窃取 | 未证实 | 初始上报只有变量名称 |
| 全球成功入侵数量与经济损失 | 未公布 | 不应推算 |
如何排查 Claude Code 插件 SSH 后门
如果你在 10 月 29 日至 30 日期间通过 Cursor 市场安装或自动更新过 Claude Code 扩展,建议先做一次快速自查。下面的 Node.js 脚本只读取公开披露的痕迹路径,不做任何修改:
// 只读排查:检查公开披露的入侵痕迹(不能单独作为结论)
const fs = require("fs"), os = require("os"), path = require("path");
const home = os.homedir();
const checks = [
path.join(home, ".ssh", "authorized_keys"),
path.join(home, ".config", ".smt"),
path.join(home, ".config", ".smtk"),
path.join(home, "Library", "LaunchAgents", "com.apple.sysmond.plist"),
path.join(home, ".config", "smt.cmd"),
path.join(home, ".config", "smtk"),
];
for (const p of checks) {
if (!fs.existsSync(p)) continue;
const hit = p.endsWith("authorized_keys")
? fs.readFileSync(p, "utf8").includes("svc-telemetry")
: true;
if (hit) console.log("⚠️ 发现可疑痕迹:", p);
}
脚本命中任何一项,都应进一步核对文件哈希、SysMon 计划任务、进程和网络记录,例如是否连接过 134.209.82[.]225 的 22 或 8099 端口。Cursor 官方公告还提供了 macOS 与 Windows 的检查和修复脚本,建议在理解脚本权限之后再执行。
对于手头的可疑扩展文件,也可以借助大模型做一轮辅助代码审查,重点看文件开头是否有调用 child_process、写 authorized_keys、建立 ssh 连接的 IIFE。下面是最简调用示例:
import openai
client = openai.OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.apiyi.com/v1" # API易 OpenAI 兼容接口
)
head = open("extension.js", encoding="utf-8", errors="ignore").read(10000)
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "请审查这段 JS 开头是否存在可疑的子进程、SSH、持久化或外连行为:\n" + head}]
)
print(resp.choices[0].message.content)
查看完整审查脚本(含哈希比对)
import hashlib
import sys
import openai
# 公开披露的恶意 extension.js SHA-256
KNOWN_BAD = {
"ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15",
}
KEYWORDS = ["child_process", "authorized_keys", "svc-telemetry",
"LaunchAgents", "schtasks", "crontab", "8099", "-R"]
client = openai.OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.apiyi.com/v1" # 使用 API易 统一接口
)
def sha256(path: str) -> str:
h = hashlib.sha256()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(1 << 20), b""):
h.update(chunk)
return h.hexdigest()
def review(path: str, head_size: int = 10000) -> None:
digest = sha256(path)
print("SHA-256:", digest)
if digest in KNOWN_BAD:
print("⚠️ 命中已公布的恶意哈希,请立即隔离设备并按官方指引处置")
head = open(path, encoding="utf-8", errors="ignore").read(head_size)
hits = [k for k in KEYWORDS if k in head]
print("文件开头命中关键词:", hits or "无")
prompt = (
"你是安全审计助手。下面是一个 IDE 扩展入口文件的开头部分,"
"请判断是否存在在模块加载时立即执行的代码,"
"并列出涉及子进程、SSH 密钥、持久化、网络外连的可疑片段。\n\n" + head
)
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
max_tokens=1200,
)
print(resp.choices[0].message.content)
if __name__ == "__main__":
review(sys.argv[1] if len(sys.argv) > 1 else "extension.js")
建议:模型审查只是辅助手段,不能替代 EDR 日志和官方指标比对。如果需要对比不同模型的代码审查效果,可以通过 API易 apiyi.com 用同一个 Key 切换调用。新用户有免费测试额度。另外,送审前请确认代码中没有业务敏感信息。
确认恶意扩展执行过之后,请依次完成以下步骤:
- 保留调查证据并隔离设备;
- 清理恶意文件、启动项和 SSH 公钥;
- 评估这台设备能访问的仓库、云凭证、会话令牌和 API Key 是否面临后续风险;
- 无法恢复可信状态时重建系统,并在可信设备上轮换全部凭证。
常见问题 FAQ
Q1:66 行 JavaScript 是指整个 Claude Code 插件吗?
不是。66 行指的是插入在 `extension.js` 最前面的恶意加载器,从第 1 行到第 66 行,约 7,386 字节。正常插件代码有 3.6MB 以上,仍在其后照常运行。
Q2:这和提示词注入攻击有什么区别?
提示词注入是诱导模型输出或执行危险操作,而这次是扩展代码在加载时直接执行。整个过程不经过 Claude,不需要对话,也不需要模型同意。即使你从没用过插件里的 AI 功能,只要扩展被加载,代码就可能运行。
Q3:从官方 npm 或 VS Code 市场安装的 Claude Code 受影响吗?
微软已确认,Visual Studio Marketplace 和官方 npm 包 `@anthropic-ai/claude-code` 未受影响,Open VSX 也没有发现对应恶意版本。受影响的仅是 Cursor 市场分发的 2.1.312 和 2.1.313,判断时还要结合来源和文件哈希。
Q4:环境变量里存了 API Key,需要更换吗?
初始上报只包含变量名称,没有上报变量值。但如果你的设备确认运行过恶意代码,后门存在被用来读取凭证的可能,稳妥做法是在可信设备上轮换。对存放在环境变量中的 API易 apiyi.com 等平台的 Key,也建议一并更换,并改用更安全的密钥管理方式。
Q5:开发 AI 应用时如何降低这类风险?
建议做到以下几点:开发机不长期以明文环境变量保存高权限 Key,不同项目使用不同 Key,并定期审计 IDE 扩展。通过 API易 apiyi.com 这类聚合平台调用模型,可以用一个 Key 覆盖多家模型,减少散落在本地的凭证数量,出问题时也只需轮换一处。
66 行 JavaScript 后门事件 Key Takeaways
- 攻击本质:Cursor 扩展市场遭供应链投毒,Claude 模型本身没有被攻破
- 触发方式:66 行 IIFE 加载器在扩展加载时自动执行,不需要用户进行任何操作
- 后门结构:两组 SSH 密钥配合反向隧道,完全复用系统自带工具
- 事实边界:5000 是受影响用户上限,API Key 实际值被盗未证实
- 处置要点:卸载插件不等于清除后门,需要多维度排查并在可信设备上轮换凭证
- 防护习惯:减少本地明文 Key,可借助 API易 apiyi.com 统一管理模型调用凭证
总结
66 行 JavaScript 后门事件说明了三件事:
- 改动小,危害大:只需在 3.6MB 文件前插入 0.2% 的代码,一个可信扩展就会变成后门载体。
- 权限决定风险:IDE 扩展拥有完整的 Node.js 执行能力,普通用户权限下也能完成密钥写入和持久化。
- 下架不等于结束:已安装的恶意组件可能延迟运行、持续外连,必须单独排查和清理。
如果你在暴露窗口内使用过 Cursor 市场的 Claude Code 扩展,请对照官方指标完成排查,并轮换可能受影响的凭证。日常开发中,建议收敛本地凭证的数量,例如通过 API易 apiyi.com 用统一的 Key 调用多家模型,降低单点泄露带来的影响面。
📚 参考资料
- Cursor 官方安全公告:事件时间、版本、哈希及清理脚本
- 链接:
cursor.com/blog/claude-code-extension-security-notice -
说明:排查与修复的第一手依据
-
Microsoft Security Research:完整攻击链与 MITRE ATT&CK 映射
- 链接:
microsoft.com/en-us/security/blog/2026/10/30/inside-malicious-claude-code-branded-cursor-extension-persistent-ssh-backdoor/ -
说明:涵盖供应链边界、SSH 机制与持久化分析
-
Phorion:66 行加载器与各平台实现缺陷
- 链接:
phorion.io/blog/offical-claude-code-vsx-compromise/ -
说明:包含环境变量筛选与 Linux crontab 缺陷细节
-
StepSecurity:11 月 1 日样本精确比对
- 链接:
stepsecurity.io/blog/claude-code-extension-trojanized -
说明:给出文件大小差异和版本标识伪装证据
-
Expel:4 起真实客户事件调查
- 链接:
expel.com/blog/blog-fake-claude-code-extension-cursor-ssh-backdoor/ -
说明:记录了延迟运行与漏报案例
-
OpenSourceMalware:恶意插件内部结构分析
- 链接:
opensourcemalware.com/blog/trojanized-claude-code-extension-plants-persistent-ssh-backdoor - 说明:确认了加载器位置与执行方式
作者:APIYI 技术团队
技术交流:欢迎在 API易 apiyi.com 网站首页联系我们,更多资料可访问 docs.apiyi.com 文档中心
