On Thursday 29 October, for about eleven hours, the Claude Code extension for VS Code distributed through the Cursor marketplace carried a backdoor. Cursor has published a security notice and the security firm Phorion a detailed analysis of the malicious code. Claude Code is a tool I use every day, so I wanted to understand properly what happened and how to check whether you’re affected.
What happened
According to Cursor, between 2:27 and 13:35 Pacific time on 29 October, two modified versions of the Anthropic.claude-code extension, 2.1.312 and 2.1.313, were published on its marketplace for macOS and Windows. Cursor says those versions weren’t developed by Anthropic, but according to Kevin Beaumont and Phorion, they were distributed through Anthropic’s official account on that marketplace. According to Ars Technica, Cursor estimates that at most 5,000 users were affected, and Anthropic released 2.1.314 a few hours later.
What’s still unknown is how the attackers got access to that account. Neither Cursor nor Anthropic has explained it, and when Ars published its piece Anthropic still hadn’t publicly warned its customers.
The detail that makes it especially sensitive: in Cursor extensions update automatically by default. There was no need to install anything new; having the extension and opening the editor that day was enough.
How the malicious code works
Phorion explains that the attacker prepended a function to the minified extension.js that runs as soon as Node loads the file, before the extension is even activated. The rest of the bundle is the normal extension, so at first glance everything worked the same. From there it does four things:
| Stage | What it does |
|---|---|
| 1. SSH access | Adds an attacker public key, with the comment svc-telemetry, to ~/.ssh/authorized_keys and tries to enable the local SSH server |
| 2. Reverse tunnel | Opens an outbound SSH connection to the attacker’s server with -R *:0:localhost:22, so they can reach the victim’s port 22 through the tunnel |
| 3. Persistence | On macOS, a LaunchAgent disguised as com.apple.sysmond.plist; on Windows, a scheduled task or a startup script. It retries the tunnel every 60 seconds, even after the editor is closed |
| 4. Reconnaissance | Sends the attacker the hostname, username, OS, public IP, Git email and up to 40 environment variable names containing KEY, TOKEN, SECRET, PASS, AWS or GCP |
flowchart LR
A["Extension auto-updated"] --> B["Key in authorized_keys"]
B --> C["Reverse SSH tunnel"]
C --> D["Attacker server"]
D -->|"comes in through the tunnel"| E["Victim's local SSH"]Stage 4 seems the most telling to me. It doesn’t steal the variables’ values, only their names, but that’s enough to take inventory: knowing which machines have AWS or GCP credentials or API tokens, and deciding which ones are worth entering later through the tunnel.
The malware’s own bugs
Here comes the almost comic part. The code has bugs that in many cases kept the backdoor from fully working:
- On macOS it checks whether remote login is off with
systemsetup -getremotelogin, but without admin rights that command doesn’t return “Off”, it returns an error message, and it exits with status 0. Since the script only tries to enable SSH if the output contains “Off”, it never tries. The key and persistence get installed, but if the Mac didn’t already have SSH enabled, the tunnel reaches a closed port 22. - On Windows it passes the PowerShell command through a function that uses
/bin/sh, which doesn’t exist on a normal install.
Cursor sums up that, unless the editor was running with admin privileges, the step to enable SSH failed. It also worked with the provider hosting the attacker’s server to take it offline. But neither Cursor nor Phorion presents this as a reason to relax: the key, the persistence and the data beacon did work, and if someone had SSH enabled or turns it on later, the door is waiting.
How to check whether you’re affected
If you use Cursor with the Claude Code extension on macOS or Windows and the editor updated it that day, Cursor suggests checking for the attacker’s key. On macOS:
grep -qs svc-telemetry ~/.ssh/authorized_keys && echo "svc-telemetry key found" || echo "No key found; machine not impacted"
It’s also worth looking for the other traces Phorion describes:
ls -la ~/Library/LaunchAgents/com.apple.sysmond.plist ~/.config/.smt ~/.config/.smtk 2>/dev/null
pgrep -fl "localhost:22"
If anything shows up, uninstalling the extension isn’t enough, because the persistence runs on its own. Cursor has published cleanup scripts for macOS and Windows, and the recommended steps are: isolate the machine, remove the key, the LaunchAgent or scheduled task and the tunnel processes, consider rebuilding the machine, and rotate from another machine the credentials that user had access to, starting with those matching those variable names.
My takeaway
A couple of weeks ago I wrote about how rarely package managers check code integrity. This case is another side of the same problem: there was no fake package with a similar name, but a malicious version published from the legitimate account, on a channel that updates itself. No signature check on the user’s side would have caught it if the account doing the signing is the real one.
And editor extensions are a very attractive target. They run with the user’s permissions, see the source code and project files, and developer machines usually hold exactly what an attacker is after: SSH keys, tokens and cloud credentials in environment variables. A couple of measures that seem sensible to me after this: disable automatic extension updates on machines with access to important infrastructure, and don’t keep production credentials as permanent environment variables on your work laptop.
The main question remains open: how Anthropic’s account on the Cursor marketplace was compromised. Until one of the two companies explains it, we won’t know whether it was a failure on one side, on both, or in the publishing process itself.
Source: Official Claude Code Extension Compromise: Security Advisory, Calum Hall, Phorion, and Security notice: malicious version of Anthropic.claude-code, Cursor. More context from Ars Technica.




