
On 29 October 2026 a malicious Claude Code extension, version 2.1.313 and self-identified as anthropic.claude-code, was published to the Cursor Marketplace. The Claude Code Cursor backdoor is a 66-line loader in extension.js that runs on module load and tries to leave a persistent SSH path on the developer host.
Key takeaways
- On 29 October 2026, Cursor Marketplace build anthropic.claude-code 2.1.313 carried a 66-line loader prepended to extension.js.
- The loader runs on module load, before any Claude chat, and the package declares no npm lifecycle scripts.
- It appends an Ed25519 key commented svc-telemetry, tries to enable SSH, and opens a reverse tunnel that reconnects about every 60 seconds.
- Persistence is a user LaunchAgent on macOS, user cron on Linux, and a SysMon task or Startup-folder script on Windows.
- OpenSourceMalware called the npm package, the Open VSX build, and the Microsoft VS Code extension not malicious. Cursor said its marketplace copy was the compromised origin.
- If that build loaded, preserve evidence and rebuild. Deleting the extension does not close an interactive SSH path.
What landed on the Cursor Marketplace on 29 October 2026?
A single Cursor Marketplace build of Claude Code, version 2.1.313, is the artifact OpenSourceMalware called malicious. Cursor later told those analysts that this marketplace copy was the origin.
OpenSourceMalware published the analysis after Dean Hardcastle flagged the activity as it happened. The write-up also circulated on Hacker News. It opens with a blunt assertion: the official Claude Code extension in the Cursor marketplace was compromised that day. The same post then narrows it.
The authors say the provenance of the directory they analyzed is not established. The findings show that this specific artifact is malicious. They do not, by themselves, show that Anthropic’s official marketplace release or distribution infrastructure was compromised.
An update relays what Cursor told the researchers. Cursor said the Claude Code extension in the Cursor Marketplace experienced some form of compromise that day, and that this copy, not the Open VSX build, was the origin of the malicious extension.
That acknowledges a marketplace problem. It is not a public root-cause report. No CVE is referenced, no CVSS score is attached, and the write-up does not name an actor or say who owns the operator infrastructure.
Inventory has to use the package identity, not the product name alone. The malicious build identifies itself as anthropic.claude-code at version 2.1.313. Matching IDs and version strings do not prove two files are the same binary.
A team that only asks whether Claude Code is installed misses the question that scopes the incident: which marketplace, which on-disk tree, and whether extension.js matches the build the rest of the package claims to be.
The unpacked extension and the bundled binary are described as the legitimate release. The diff is extension.js. A check of the bundled binary can still miss the implant. The trusted bulk of the package provides the camouflage.
For a security lead briefing an executive, the defensible claim is narrow. A trojanized developer extension reached Cursor users through the Cursor Marketplace on 29 October 2026. The same analysts called Anthropic’s other named channels clean.
Why does the Claude Code Cursor backdoor run before a chat?
The Claude Code Cursor backdoor runs when the extension module loads, after editor startup and when the webview opens. Starting a Claude conversation is not required. A chat prompt is irrelevant to this path.
The malicious code is not a rewrite of Claude Code’s logic. It is a 66-line immediately invoked function at the top of extension.js, ahead of the legitimate bundled code. By the time the editor’s extension host finishes evaluating that file, the loader has already run.
VS Code-family extensions normally run in a separate extension-host process, with the logged-in user’s permissions, outside the webview sandbox. That process can touch the home directory, SSH files, local services, scheduled tasks, and outbound clients.
This is not a prompt-injection story, and it is not a jailbreak of the model. The model is not asked to do anything. Loading the extension module is enough.
Lifecycle-hook monitoring misses it. OpenSourceMalware states the package declares no install, build, prepare, preinstall, or postinstall scripts. Execution happens at extension runtime.
npm ignore-scripts, lockfile review, and postinstall alerts cover a different path. Disabling lifecycle scripts does not stop JavaScript the editor runs when it loads an extension. If detection only watches npm, pnpm, and yarn, this build slips past it.
Nearly every exception in the loader is swallowed. When a step fails, the legitimate extension still loads, and the developer sees Claude Code come up. Failed sudo, a missing sshd, or a blocked outbound port does not look like a broken extension.
“The IDE still works” is not a negative test. The injected stage downloads no second executable. Network behavior in the analysis is public-IP text lookups, JSON beacon uploads, and an SSH tunnel.
Helpers and keys are built from content already in the extension. The beacon response is discarded, not run. It is a self-contained trojanized extension, not a dropper.
What access does the implant try to keep?
The implant tries to keep an SSH login for an attacker-held key, a reverse tunnel back to local port 22, and a way to start that tunnel again after reboot or login.
If a home directory exists, it creates ~/.ssh with mode 0700 and appends an Ed25519 public key commented svc-telemetry. It sets authorized_keys to mode 0600. If the marker is already present, it records that fact and does not add a duplicate.
OpenSSH keeps one public key per line, so the append leaves existing keys in place. Uninstalling the extension does not delete the line. Signing in with your own key does not show the file is clean. Read the lines.
It also tries to enable remote login, and failure does not stop the chain. On macOS it attempts a non-interactive sudo change to the Remote Login setting. On Linux it looks for sshd or ssh through systemctl and tries several start commands.
On Windows, PowerShell is used to install OpenSSH Server, set automatic startup, and start sshd. Those steps can fail without privileges. A host where sshd never started can still hold the new key. Check each step that completed.
The tunnel makes this an interactive path. An embedded OpenSSH private key, stored base64-encoded in the extension, is decoded to a temporary file named with a .stk_ prefix. The client connects repeatedly as the remote user tunnel and requests a forward to local port 22.
Host-key verification is off, the user’s known-hosts file is ignored, and only the embedded identity is used. On Unix-like systems it prefers autossh and otherwise uses ssh. It reconnects after 60 seconds.
The laptop opens the outbound session, and the operator reaches local port 22 through it. Blocking new inbound connections to port 22 does not, by itself, protect a host that keeps the tunnel up.
A normal-looking known_hosts file is also not evidence the tunnel never ran, because the client was configured not to write to known_hosts.
How is persistence split by operating system?
Three platform branches write persistence. The privilege that results is not the same on each one. A failed privileged step can still leave the user-level pieces that succeeded.
- macOS: ~/.config/.smt and ~/.config/.smtk, plus a user LaunchAgent, com.apple.sysmond.plist, with RunAtLoad and KeepAlive, loaded through launchctl. The Apple-like name is a user agent. It runs as that user.
- Linux: the same style of helper files under ~/.config, plus an @reboot line in the user crontab. That job runs as the user.
- Windows: .config\smt.cmd and .config\smtk, then an on-start scheduled task named SysMon set to run as SYSTEM. If the task is not confirmed, a script is copied to the Startup folder. SYSTEM applies only when task creation succeeded.
Before the tunnel, the loader collects hostname, local username, operating system, CPU architecture, home directory, current working directory, the global Git email from git config, and, as names only (not values), up to 40 environment variables matching KEY, TOKEN, SECRET, PASS, AWS, or GCP.
After about 1.5 seconds it resolves the public IP through public lookup services and POSTs the JSON to an HTTP beacon on localhost and to the operator host. The response is drained and ignored. Returned data is not saved as a payload or as configuration. No blockchain payload locations were found.
Names without values do not limit a later SSH session. If the tunnel comes up, the operator can read the account directly. Git email and a developer home directory can tie the machine to a person and to the repos they push.
A user key plus a user LaunchAgent is enough to return to a laptop holding cloud tokens and source. A Windows task that actually runs as SYSTEM is a wider foothold. Treat this as an SSH backdoor with three OS branches and a one-minute reconnect, not as a uniform SYSTEM worm.
Which Claude Code channels were called clean?
OpenSourceMalware states that the @anthropic-ai/claude-code npm package, the Open VSX build, and the Microsoft VS Code Claude Code extension are not malicious.
That is the analysts’ finding on the artifacts they compared. agent::offense has not re-tested those three channels for this article. Use it to stop a blast-radius rumor, and keep that confidence label in any executive brief.
| Channel | What the analysis says | What a defender should do anyway |
|---|---|---|
| Cursor Marketplace, anthropic.claude-code 2.1.313 | Malicious build. Cursor later said this copy was compromised and was the origin, not Open VSX. | Inventory the host and treat a confirmed install as an incident. |
| @anthropic-ai/claude-code on npm | Stated not malicious. | Keep lifecycle-script monitoring. Do not treat it as the IDE check. |
| Open VSX Claude Code extension | Stated not malicious. Cursor pointed away from Open VSX as the origin. | Confirm the install source, not only the extension ID. |
| Microsoft VS Code marketplace Claude Code extension | Stated not malicious. | Apply the same inventory if developers run both editors. |
| Anthropic release pipeline | Not shown compromised by this artifact alone. | Wait for Anthropic before claiming a vendor-build breach. Remove 2.1.313 from Cursor now. |
The analysts had not established who published the Cursor file, beyond Cursor’s later statement that the marketplace copy was the origin. On this record there is no evidence the npm package, the Open VSX build, the VS Code build, or Anthropic’s distribution infrastructure was compromised.
What Cursor did say is specific. Its marketplace Claude Code extension was compromised that day, and Open VSX was not the origin.
The same class of failure shows up in malicious git configs that make coding agents run attacker code when a developer opens a tree. Marketplace trust sits one level above that: the IDE fetches the tool, the tool runs as the user, and the model is never asked.
Should you rebuild after the Cursor Marketplace compromise?
If version 2.1.313 loaded, plan on a rebuild. OpenSourceMalware’s point is direct: an interactive SSH path means the files you can see may not be the full compromise. Disconnect, preserve evidence, and only then remove the extension and its persistence.
Extension removal deletes the loader. It does not delete an authorized_keys line, a LaunchAgent, a crontab entry, a scheduled task, or a Startup script. It does not end an SSH session already open, and it does not show whether that session read tokens or changed a Git remote.
Preserve the extension directory, persistence entries, SSH configuration, and editor, shell, authentication, and network logs. Hunt unexpected authorized_keys lines, the comment svc-telemetry, and long-running ssh or autossh processes that forward to local port 22.
On macOS, check loaded LaunchAgents for com.apple.sysmond.plist and each user’s authorized_keys. On Linux, check the ~/.config helpers and user crontabs for an @reboot entry. On Windows, check the SysMon task and the Startup-folder copy.
A reverse tunnel needs no new inbound hole through the perimeter firewall. Block the operator address named in the original advisory on SSH and on the beacon port, after you have preserved logs. Do not expect a fresh known_hosts record of that server.
After a confirmed load, rebuild, then rotate from a known-clean system every credential that account could reach: SSH keys, cloud CLIs, Git credentials, and package-registry tokens. The beacon carried environment-variable names only. An interactive session could still have read the values.
Until on-disk extension.js has no prepended loader, block or pin Cursor Marketplace installs of anthropic.claude-code at 2.1.313. Other versions are outside this analysis. No CVE in the write-up is not a reason to leave that build installed.
Airlock, the runtime firewall for AI coding agents, constrains what a coding agent may do after install. That control is separate from this incident. Nothing here shows it would have stopped an extension-host SSH implant that runs before any model call.
What should a pentest scope add after this?
Put IDE marketplaces, installed extension hashes, and developer-secret reach in the same scope as MCP servers and agent toolchains.
This was not a clever prompt. A name the developer already trusted delivered code that ran as the developer, with no model call. The test is whether you can separate a Cursor Marketplace build, an npm tarball, and an Open VSX build when all three are named anthropic.claude-code.
Ask for install source, version, and a hash of the installed tree. If those fields are missing from inventory, the control is not there. A scanner that only reads package.json will keep passing this install.
Then test blast radius from one developer laptop. The loader wanted SSH, a forward to port 22, a Git identity, and the names of cloud-shaped variables. That combination usually means source, CI, and a daily cloud account are in reach.
An AI supply chain security audit should cover extension marketplaces and hashed install paths, not only weights, datasets, and package graphs. The 66-line prefix is small beside a legitimate bundle.
MCP server and tool-chain security testing hits the same user-level trust boundary on another install path. The three persistence branches and the 60-second reconnect exist so one crash or one reboot does not end access.
FAQ
Was the Claude Code extension on the Cursor Marketplace compromised?
Cursor told OpenSourceMalware that the marketplace Claude Code extension experienced some form of compromise on 29 October 2026, and that this copy, not Open VSX, was the origin. The public note names no CVE and is not a root-cause report.
Is the official Claude Code npm package malicious?
OpenSourceMalware states the @anthropic-ai/claude-code npm package is not malicious. That covers the artifacts those analysts compared. It does not replace a hash of the copy an IDE actually installed.
What does Claude Code extension version 2.1.313 do?
In the Cursor Marketplace build, extension.js starts with a 66-line loader. On load it collects host facts, appends an SSH key commented svc-telemetry, tries to enable SSH, opens a reverse tunnel, writes persistence, and beacons. The rest of the package is described as the normal extension.
Did Anthropic's Claude Code get hacked?
This record does not show a compromise of Anthropic's npm package, Open VSX build, VS Code extension, or distribution infrastructure. It does record Cursor's statement that the Cursor Marketplace copy was compromised.
Is the VS Code Claude Code extension safe?
OpenSourceMalware called the Microsoft VS Code Claude Code extension not malicious, and called the Open VSX build not malicious. Confirm the install source on disk. The malicious artifact in this analysis is the Cursor Marketplace build 2.1.313.
Should you rebuild after the Cursor Marketplace compromise?
If 2.1.313 loaded, yes. The extension leaves an interactive SSH path, so removing visible files does not prove the operator stopped at the loader. Preserve logs, rebuild the host, and rotate credentials from a known-clean system.
If your developers install coding agents from a marketplace, the test is the installed artifact and the secrets that host can already reach. agent::offense runs that work as an AI agent penetration test covering extension trust, tool-use paths, and the blast radius from one laptop.