Deep Stackby Burak
All posts
6 min read

The Update That Installed a Backdoor

Your coding assistant did not get hacked. Its update channel did — and the update arrived the way updates are supposed to arrive.

The Update That Installed a Backdoor

The interesting thing about the trojanized Claude Code extension is not that a developer tool shipped malware. It is that nothing about the delivery looked wrong. The build carried the official extension name, anthropic.claude-code, it arrived through Cursor’s own extension marketplace as an ordinary update, and it ran the moment the editor loaded it — before any Claude conversation started, before any prompt was typed, before the user did anything at all. The Hacker News discussion, which put the story at 942 points and 538 comments at fetch time, kept circling the same uncomfortable question: if the official channel is the attack, what is left to trust?

What shipped

Cursor says a modified build of Anthropic’s Claude Code extension for Visual Studio Code was available in its marketplace from about 2:27 a.m. to 1:35 p.m. Pacific time on October 29, 2026 — roughly eleven hours. Cursor’s original notice named version 2.1.313; a revised notice on October 30 added version 2.1.312, and said both versions were pulled. Cursor says Anthropic did not build the modified versions, that at most 5,000 users received them, and that it will contact affected users directly. The clean replacement, version 2.1.314, was published by Anthropic in the early hours of October 30.

The mechanism, as analyzed by macOS security firm Phorion and confirmed in outline by Cursor, is a 66-line loader prepended to the extension’s main script, extension.js. Because it sits at the top of the file, it executes as soon as Node loads the extension, ahead of the extension’s own activation callback. No click, no prompt, no conversation required. The loader then does four things, and the order matters because each one is designed to survive the removal of the others.

First, it plants a door: it appends an attacker’s Ed25519 public key, labelled svc-telemetry, to the user’s ~/.ssh/authorized_keys file. Anyone holding the matching private key can then log in as that user, if the machine’s SSH service is reachable. Second, it tries to open that door, attempting to enable the SSH service with system tools on each platform. Third, it calls home through a reverse tunnel: an outbound SSH connection to 134.209.82.225 that asks the attacker’s server to forward a port back to the victim’s port 22, retrying every 60 seconds. A reverse tunnel is the detail that defeats the usual home defense, because the connection is started from inside — a router or office firewall that blocks incoming traffic does not stop it. Fourth, it makes itself permanent: a LaunchAgent named com.apple.sysmond on macOS, chosen to look like Apple’s own, an @reboot cron entry on Linux, a scheduled task named SysMon on Windows. Along the way it sends one plaintext report to the same server on port 8099: hostname, username, operating system, home folder, global Git email, public IP, and the names — not the values — of up to 40 environment variables matching KEY, TOKEN, SECRET, PASS, AWS, or GCP.

That sounds like a total compromise of every machine that took the update. It isn’t — quite.

The catch that limits the damage, and the part it doesn’t

The SSH step is where the attack runs into the operating system’s own permissions. Turning on an SSH service needs administrator rights the extension does not have on most machines, so Cursor says the tunnel step likely failed on most macOS and Windows hosts. Phorion found a matching bug in the macOS path: run without root, the check for whether Remote Login is off returns an error instead of the word Off, so the script never even attempts to enable it. Cursor also worked with the hosting provider to take 134.209.82.225 offline, so the tunnel and the beacon no longer function.

But the parts that did not need admin rights still landed. The key in authorized_keys and the persistence task are installed either way, and they outlive the extension. Uninstalling the extension, or updating to 2.1.314, replaces the extension file and touches none of them. That is the sentence every affected user needs to hear clearly: updating is not remediation. Cursor ships remediation scripts for macOS and Windows that exit with an error if anything is left, and Phorion lists the Linux cron entry to remove by hand. The machines at highest risk are the ones where SSH was already on — a Linux box running sshd, a Mac with Remote Login enabled — because there the planted key would have let an attacker in as the user while the server was up. Cursor’s advice for those machines is to consider a rebuild.

There is also an attribution gap worth stating plainly. How the modified build got into Cursor’s marketplace has not been explained by anyone. Early reports pointed at Open VSX, the open extension registry many VS Code-based editors use; those reports were corrected, and the build was traced to Cursor’s marketplace. Cursor says it shut the marketplace down, audited access, rotated its keys, rebuilt the marketplace, and found no other tampered extensions. Anthropic, as of October 30, had published no statement the coverage could find. And one registry question remains genuinely unresolved: StepSecurity reported that 2.1.313 was briefly listed on Microsoft’s marketplace and now returns a 404, which today’s registry data can neither confirm nor rule out, because a removed version leaves no entry in the list. Treat any 2.1.313 install, from any source, as bad.

Why this one lands differently

Supply-chain compromises are not new, and developer tools are not a new target. What makes this one land differently is the position the extension occupies. An editor extension runs with your rights. It can read your SSH keys, your cloud credentials, and every repository you can open. The Claude Code extension in particular sits in the exact workflow where developers now paste their most sensitive context — production credentials in environment variables, private repositories, infrastructure code — and the beacon’s variable-name filter shows the attacker knew what to look for. Names are not keys, but they are a map of where the keys live.

The deeper problem is auto-update as a trust decision. The victims did not download a suspicious file. They did what every security guide tells them to do: they kept their tools current, and the current version was the malicious one. The Hacker News discussion focused, rightly, on the asymmetry: one compromised build reaches thousands of machines in hours, while the cleanup is manual, per-machine, and requires the user to know the attack happened at all. Cursor says it will contact affected users directly, which is the right move, but contact lists depend on knowing who updated in an eleven-hour window, and the first reports of this incident came from researchers, not from the marketplace.

For builders, the takeaway is practical: treat extension auto-update as a deployment you own, not a default you accept. VS Code-based editors let you turn it off with the extensions.autoUpdate setting, pin a version with Install Another Version, and list every installed version with a single command. Keeping that list per machine turns the next incident into a one-line search instead of a forensic project. On any machine that ran Claude Code 2.1.312 or 2.1.313 from Cursor’s marketplace on October 29, the check is one line — search authorized_keys for svc-telemetry — and it should be run on every machine, not only the ones you suspect, because the update arrived silently and the cleanup does not happen by itself.

The extension updated itself into a backdoor, and the backdoor’s most durable feature is not the tunnel or the key. It is the assumption it exploited: that an update from the official channel is, by definition, safe. That assumption is now a line item in someone’s incident report.

Source: The backdoored Claude Code 2.1.313 build in Cursor’s marketplace, explained

Latest from Deep Stack

5 min read

Open Weights, Closed Map

Baidu's ERNIE 5.5 Flash Base is downloadable, cheap per token, and 280 gigabytes of fine print.