1. Home
  2. Blog
  3. Compromised Claude Code extension

Artificial intelligence · 9 min read

Your coding agentis a supply chain.

For roughly 11 hours, a tampered build of the Claude Code extension shipped a persistent SSH backdoor from Cursor's marketplace. Here is exactly what the payload did, and why your developer fleet is a softer target than your cluster.

By Kaleido LabPublished on

In short

  • Versions 2.1.312 and 2.1.313 of the Anthropic.claude-code package on Cursor's marketplace executed an SSH backdoor at module load, before the extension's activate() callback. Around 5,000 developer machines are believed affected.
  • The payload appended an Ed25519 key labelled svc-telemetry to ~/.ssh/authorized_keys, installed persistence (LaunchAgent, @reboot cron, scheduled task) and beamed host inventory to a command server.
  • Two bugs in the malware limited the damage — not anyone's security stack. The lesson is not "AI extensions are dangerous", it is "an IDE marketplace is a package registry running with user privileges".

The real problem: an extension runs as you

An IDE extension is not a sandboxed browser plugin. It is Node.js code loaded inside the editor process, with the permissions of the user who installed it: read access to every repository on disk, to ~/.ssh, to environment variables, to Git credentials, to network sockets. On a 2026 developer laptop that is the most valuable asset in the company — usually more than the staging cluster.

For years this attack surface stayed theoretical because extensions were few and published by their own vendors. Coding agents changed the scale: every developer now installs, updates and occasionally trials several extensions per month, often from third-party marketplaces, with auto-update on. That is the npm threat model, except the package gets full access to source code and secrets.

So the October 29 incident is not an isolated accident. It is the first large-scale public demonstration of what "installing an agent" actually means: the model, the prompt and the tool loop are only the visible layer. The attack vector is the package that carries them.

11 hours, two versions, 5,000 machines

The timeline is documented in Cursor's security notice and in Phorion's endpoint analysis, which detected the activity on customer machines. Between 2:27am and 1:35pm PT on October 29, a modified build of the official Claude Code extension was published to Cursor's VS Code marketplace for macOS and Windows. Per Kevin Beaumont, Cursor estimates roughly 5,000 developer systems were impacted. Cursor pulled the package, shut the marketplace down as a precaution, rotated its keys and had the attacker's server taken offline; Anthropic stated it had no part in building or publishing the tampered build.

Two versions are in scope: 2.1.312, then 2.1.313. The follow-up 2.1.314 removes the payload from the package — it does not clean machines that already ran it. That is the part most summaries missed: the update closes the door, it does not remove the intruder.

Anatomy of the payload

The technical detail is worth reading, because it shows how little sophistication was required. The compromised extension.js begins with an IIFE prepended to the minified bundle. It pulls in child_process, fs, os, path, http and crypto, and executes as soon as Node loads the file — before the extension's activate() callback. No user interaction required: opening the editor is enough.

The sequence after that is textbook:

  • Recon. Collect hostname, username, OS, architecture, home path, environment variable names, working directories, configured Git email and public IP. The inventory is POSTed to /beacon on port 8099.
  • Access. Append an attacker-controlled Ed25519 public key to ~/.ssh/authorized_keys, with 0700/0600 permissions. The key carries the comment svc-telemetry — useful for the attacker's own bookkeeping, and for your detection.
  • Tunnel. Attempt to enable the local SSH service (systemctl on Linux, Remote Login on macOS, OpenSSH Server on Windows) and open a reverse SSH tunnel, retried roughly every 60 seconds.
  • Persistence. On macOS a LaunchAgent at ~/Library/LaunchAgents/com.apple.sysmond.plist running /bin/sh ~/.config/.smt; on Linux an @reboot cron entry; on Windows a SysMon scheduled task with a Startup-folder script as fallback.

The indicator table, if you are hunting:

ArtefactPlatformRole
~/.ssh/authorized_keys (comment svc-telemetry)AllAttacker's Ed25519 key
$TMPDIR/.stk_<10 hex>AllTunnel private key in the temp directory
~/.config/.smt and ~/.config/.smtkmacOS, LinuxPersistence script and recreated key
~/Library/LaunchAgents/com.apple.sysmond.plistmacOSLogin-time LaunchAgent
@reboot cron entry pointing at ~/.config/.smtLinuxRestart persistence
SysMon task plus sysmon.cmdWindowsScheduled task and Startup fallback

The two bugs that saved the day (by accident)

The most interesting part of this story is that the attack largely failed because of development mistakes, not defences. On macOS the script checks Remote Login state with systemsetup -getremotelogin without elevation. Run as a standard user, that command prints "You need administrator access to run this tool" and exits with status 0. The /Off/i test therefore never matches, and the SSH enablement step is skipped entirely. On Windows, the service install path goes through a helper that hardcodes /bin/sh, which does not get far on a machine without a POSIX shell.

Net effect on most hosts: the SSH key and the persistence were planted, the beacon fired, but interactive access failed because no SSH daemon was listening. That does not make the incident benign — recon and persistence both succeeded, and credential access over a later foothold was still on the table. It says something more useful though: the gap between a major incident and a catastrophe was two lines of code. Do not count on that next time.

Detect and remediate without an EDR

The baseline check is one command. On macOS and Linux:

grep -qs svc-telemetry ~/.ssh/authorized_keys && echo "key found" || echo "not impacted"

On Windows, check $HOME\.ssh\authorized_keys and C:\ProgramData\ssh\administrators_authorized_keys in PowerShell. Then sweep for the artefacts above: ~/.config/.smt, ~/.config/smt.cmd, com.apple.sysmond.plist, the SysMon task, an @reboot cron entry, and .stk_* files in the temp directory. An antivirus without the sample in its database will not help you; these paths will.

If a host is positive, order matters: isolate it from the network, remove the key and the persistence mechanisms, kill tunnel processes, then from another machine rotate every credential reachable from that host — Git tokens, cloud keys, browser sessions, secrets sitting in environment variables. The initial collection only grabbed variable names, but nothing guarantees a later foothold would not widen it. And rebuild is the safer option when the host had production access.

Production checklist

  1. Treat the IDE marketplace as a package registry. Pin and inventory versions, disable auto-update on machines holding production secrets, and mirror approved extensions internally.
  2. Alert on svc-telemetry and the artefact paths. Any change to authorized_keys outside your onboarding flow should page someone. Cheaper than an EDR, and it catches benign cases too.
  3. Separate the machines. The laptop that holds production cloud keys should not be the one where you trial three agent extensions a week.
  4. Rehearse rotation. This kind of incident is only clean if you know which credentials were reachable. An inventory of secrets per machine, or remediation is guesswork.
  5. Do not confuse updating with cleaning. 2.1.314 removes the payload from the package; it deletes neither the key, nor the LaunchAgent, nor the scheduled task already installed.

Need help designing reliable AI workflows, auditing an LLM architecture, or training your engineering team? See how we work at Kaleido-Lab.

Frequently asked

Another question ? Email me.

Am I affected if I use the Claude Code CLI?

No. The incident concerns the Anthropic.claude-code extension package 2.1.312 and 2.1.313 distributed on Cursor's marketplace, not the official CLI or the Visual Studio marketplace. The check takes ten seconds : grep -qs svc-telemetry ~/.ssh/authorized_keys.

Is updating to 2.1.314 enough to clean my machine?

No. The update removes the payload from the package, not what the payload already wrote : the SSH key in authorized_keys, the ~/.config/.smt script, the com.apple.sysmond.plist LaunchAgent on macOS, the @reboot cron entry on Linux, the SysMon scheduled task on Windows. Remove those artefacts, then rotate every credential reachable from the host.

How do you prevent this across a developer fleet?

Treat the IDE marketplace like an npm registry : pinned and verified versions, auto-update disabled on machines holding production secrets, an internal mirror of approved extensions, and a review of requested permissions. An EDR catches execution; it does not block a legitimate extension that turned malicious.

Should we stop installing AI extensions in the IDE?

No, but the trust model has to change. An extension runs with the user's and the IDE's privileges, including read access to every repository and to environment variables. The right trade-off : fewer extensions, frozen versions, and a separation between the laptop holding production secrets and the one used for experiments.

Is your AI pipeline auditable?

You are wiring agents into internal tooling and want the attack surface reviewed before production ? Describe your context and I will reply with a first opinion and next steps, no strings attached.

Read next