The update added a key
For eleven hours on October 29, Cursor's extension marketplace served a trojanized Claude Code extension under Anthropic's own publisher name. On load, it added an attacker's SSH key, installed a LaunchAgent and tried to open a reverse tunnel, on up to 5,000 developers' machines. In Bromure Agentic Coding, the agent doesn't come from an editor marketplace, and a payload like this one runs in a VM nobody can reach, with its tunnel refused by the egress firewall and its persistence removed by rewinding the home.
Nobody had to open a chat or approve a tool call. The editor loaded the extension, and 66 lines of JavaScript ran as the developer before Claude Code's own code did.
On October 29, between about 2:27 a.m. and 1:35 p.m. Pacific time, Cursor's
extension marketplace served a trojanized build of Anthropic's Claude Code
extension. Cursor's security
notice names
versions 2.1.312 and 2.1.313 of anthropic.claude-code, published under
Anthropic's publisher identity, and says Anthropic didn't build them.
BleepingComputer
reports that up to 5,000 developers were exposed, and The Hacker
News
notes that anyone with auto-update turned on could have received it without
doing anything.
Researchers at Phorion and OpenSourceMalware published analyses on October 30. Cursor pulled the extension, shut its marketplace down to audit it and rotate keys, and had the attacker's server taken offline. Nobody has said yet how the build got published under Anthropic's name.
What the 66 lines did
The attacker left Claude Code's code alone and put a 66-line loader in
front of it, at the top of extension.js. OpenSourceMalware describes the
pattern: "place a compact backdoor before a large legitimate bundle,
suppress errors, and let the expected application continue." The loader
ran when the editor loaded the extension and opened its webview. The
developer didn't have to start a conversation. After that, the real
extension loaded and worked.
In the meantime, the loader:
- Took an inventory. Hostname, username, OS, home and working
directories, the global git email, the public IP, and the names of up to
40 environment variables containing
KEY,TOKEN,SECRET,PASS,AWSorGCP. It sent all of it as JSON, over plain HTTP, to134.209.82.225:8099/beacon. - Added a door. It appended an Ed25519 key with the comment
svc-telemetryto~/.ssh/authorized_keys. - Tried to open it. On macOS it ran
sudo -n systemsetup -setremotelogin on, on Linux it tried to startsshd, and on Windows it installed OpenSSH Server. - Dialed out. It wrote a private key to a temp file and connected to
[email protected]with-N -R '*:0:localhost:22', a reverse tunnel that forwards a port on the attacker's server back to the developer's own SSH port. It reconnected every 60 seconds. - Made itself permanent. A user LaunchAgent named
com.apple.sysmondon macOS, a crontab@rebootentry on Linux, and a scheduled task calledSysMonon Windows.
Coding errors kept SSH from switching on for many victims, according to
BleepingComputer. The key, the persistence and the beacon landed on those
machines too.
Cursor's advice is to check for the svc-telemetry key, remove the
persistence, consider rebuilding the machine because uninstalling the
extension may not be enough, and rotate every credential the machine could
reach, "using a trusted system."
The most trusted code on the machine
An editor extension runs with the developer's full account. It can read every file in the home directory, start processes, and write a LaunchAgent that outlives the editor. Marketplaces push updates without asking, and the publisher name on this one was Anthropic's. A cautious developer who checked the publisher before installing got the backdoor too: it arrived as an update to an extension they had installed weeks earlier.
Coding agents raise the stakes. The extension that hosts the agent is the one developers grant the most: it reads the whole repository, runs commands, and sits in a process with the environment's API keys and cloud tokens. This loader took the names of those variables. Reading the values takes the same few lines.
The same morning in Bromure Agentic Coding
Bromure Agentic Coding runs Claude Code, Codex, Grok, Kimi and omp in Ubuntu VMs on your Mac. Each machine is a VM of its own, and the agent, its repositories, its package installs and its commands all live inside it. The chat and the terminals you type into are drawn by the app on your Mac. The real credentials, the proxy the VM's traffic goes through, and the record of what happened stay on the Mac too.
The agent doesn't come from an editor marketplace
There's no extension marketplace in the path: Bromure draws its own chat
window on the Mac. Claude Code is installed
into your copy of Bromure's base image by a setup step listed in a catalog
signed with the same key as Bromure's app updates. That step installs
@anthropic-ai/claude-code from npm, wrapped in Socket.dev's supply-chain
scanner. OpenSourceMalware lists the npm package among the distributions
that weren't touched.
Anything the agent installs afterwards goes through the proxy on the Mac,
and the proxy applies the machine's supply-chain policy. The age gate ships
on, with a two-day minimum: npm, PyPI, Cargo, RubyGems and Packagist
versions younger than that are removed from the registry's listing, so
latest resolves to the newest release that has been public for two days.
Cursor's malicious build was live for eleven hours. A hijacked release on
npm with the same lifetime never appears in a Bromure machine. We walked
through that case with LiteLLM's poisoned PyPI release in The release was
two hours old.
The key opens a door nobody can reach
Say a payload like this one gets into a machine anyway, through a
repository the agent clones or a tool it runs. It runs in Ubuntu, as the
machine's user. It doesn't get your macOS account, your Keychain or your
Mac's ~/.ssh.
Its svc-telemetry key goes into the VM's own authorized_keys. Machines
sit on a private network inside the app: your Mac can reach them, your
physical LAN can't, and nothing outside can connect unless you publish a
service yourself. The only route in was the reverse tunnel.
The tunnel never opens
The tunnel needs an outbound SSH connection to 134.209.82.225, and the
beacon needs plain HTTP to port 8099 on the same address. Every connection
the VM makes passes through the Mac, where the machine's Outbound
connections firewall applies. Its rules match host, IP range, protocol
and port, and with Unmatched traffic set to Deny only the hosts you
listed get through. A DigitalOcean IP on port 22 isn't on anyone's list.
The firewall refuses the tunnel, each 60-second retry, and the beacon.
Each refusal lands in the Security Timeline on your Mac, with the host, port, protocol and verdict. A deny to the same IP every minute is hard to miss, and you see it while the attacker waits for a connection.
The inventory is worth nothing
The beacon's list of variable names would have found plenty in a Bromure
machine: ANTHROPIC_API_KEY, a GitHub token, AWS settings. Every value is
a stand-in. The real credentials are encrypted on the Mac, and the proxy
swaps a stand-in for its real value only on requests to the host it belongs
to. SSH private keys aren't in the VM at all. SSH_AUTH_SOCK is a bridge
to the Mac that returns signatures, and your Mac's own ssh-agent is never
exposed. A loader that went on to read the values would get strings that
no server accepts. If it sent one of them to its own server, the proxy
would block the request, pause the VM and show This environment may have
been compromised, naming the credential and the destination.
The cleanup takes a minute
Cursor tells affected developers to remove the key and the persistence,
consider rebuilding the machine, and rotate credentials from a trusted
system. In Bromure, the rebuild is two menu items. Bromure keeps a
copy-on-write checkpoint of each machine's home every time it boots.
Rewind home… rolls /home/ubuntu back to a boot from before the
payload ran, taking the extra key and the ~/.config/.smt launcher with
it. Reset disk re-clones the system disk from the base image and takes
the crontab with it. The machine's settings, credentials and SSH keys
survive both.
The trusted system Cursor asks for is the Mac, which never ran the payload. There's nothing to rotate, because the VM never held a real credential.
Give the risky work its own machine
Credentials and firewall rules are set per machine, and machines are cheap
to make. A machine that tries out new tools, plugins and starter kits can
have no production credentials and a firewall that denies everything
except its package registries. The machine that deploys keeps its
credentials, with approval required before each one is used. For a one-off
experiment, bromure-cli vm run --rm creates a machine that is deleted
when it stops.
No marketplace in the path
The chat is part of the app. Claude Code comes from Anthropic's npm package through a signed setup step, scanned by Socket.dev.
Two days before anything new
The age gate hides package releases younger than two days. A hijacked version that lives eleven hours never resolves.
A door nobody can reach
A planted key lands in the VM's own authorized_keys, on a private network your LAN and the internet can't connect to.
Deny the unknown host
With Unmatched traffic set to Deny, the reverse tunnel and the beacon are refused, and every attempt is recorded on the Mac.
Stand-ins in the VM
Every API key and token in the VM is a stand-in, and SSH private keys never enter it. The inventory is worth nothing.
Rewind instead of rebuild
Rewind home and Reset disk remove the payload's files and persistence. Settings, credentials and keys stay.
The tool that runs the agent is part of the attack surface
Cursor and Anthropic haven't said how the build went out under Anthropic's name. For your own machine, the incident settles one point. The software that hosts your coding agent runs with your account and updates itself, and a trusted publisher name on the update proves nothing about its contents.
In Bromure Agentic Coding, your agent and everything it touches run in a VM on your Mac. That VM holds stand-ins, reaches only the hosts you allow, and can be rolled back to a boot from before something went wrong. The real keys never leave the Mac.
For infostealers that now collect coding agents' tokens and histories, read They added your agent. For a compromise that started on a developer's laptop and ended at $6.3 billion, read The laptop was the way in.