Quick Answer: This Claude Code extension backdoor shipped inside the official VS Code extension as served through the Cursor Marketplace, in version 2.1.313. On first load it planted an SSH key, opened a reverse tunnel to an attacker's server, set up persistence, and sent a host reconnaissance beacon. Check for that version and search for the svc-telemetry key in ~/.ssh/authorized_keys.

If you run Claude Code inside VS Code or Cursor, treat this as an incident until you've checked. Phorion found a Claude Code extension backdoor in a bundle served through the Cursor Marketplace, and it goes well beyond typical extension misbehaviour. It installs a persistent SSH backdoor across macOS, Linux, and Windows. A bug in the macOS code path limits the damage there, but that's not a reason to relax.

What Phorion found in the marketplace bundle

The compromised package is the extension bundle itself. Phorion's analysis, published on its blog, describes a backdoored release that contains a persistent Secure Shell (SSH) implant. Cursor has since removed the release from its marketplace and pulled the matching NPM and VS Code packages for 2.1.313, as its security notice explains.

Some coverage frames this as Anthropic being hacked. That's a bigger claim than the evidence I can see supports. The write-up describes a poisoned bundle distributed through a third-party marketplace, not a breach of Anthropic's own systems. Keep that distinction when you brief your security team, because it changes where you look for the source of the compromise.

Here's why the "only install from the official publisher" rule didn't protect people. The publisher name was on the bundle, and extensions run with the full permissions of the editor and the logged-in user. Once the module loads, it can read local files, source code, and developer tooling. Trust in the listing was the attack surface.

The payload runs before you interact with anything

Most extension risk reviews focus on what happens when a user clicks a command. This one doesn't wait. Phorion found an immediately invoked function expression (IIFE) prepended to the minified extension.js. The injected prefix loads standard Node.js modules (child_process, fs, os, path, http, and crypto) and runs as soon as Node evaluates the file.

That timing matters. The payload fires before the extension's normal activate callback runs, so you never see a prompt, a command, or a UI change. Here's the practical implication: if you're investigating, don't assume an unused extension was harmless. Loading it was enough.

Planting a key and opening a reverse tunnel

The first stage makes sure ~/.ssh exists, then appends an attacker-controlled Ed25519 public key to ~/.ssh/authorized_keys. It sets permissions to 0700 on the directory and 0600 on the file, which makes the key look like ordinary housekeeping. The key carries the comment svc-telemetry. The script checks for that string rather than the key itself, so a renamed comment would slip past it. Hunt by fingerprint, not by comment.

The second stage opens an outbound reverse tunnel. The implant decodes a separate embedded private key, with the comment svc-telemetry-tun, and runs SSH with -R *:0:localhost:22. Passing 0 tells the attacker's server to allocate a listening port dynamically, then forward any traffic arriving there back to port 22 on the victim. The tunnel runs with -N, so it never executes a remote command. It just holds the port forward open.

The flags are chosen for stealth and resilience. Host-key checking is disabled, known_hosts is ignored, BatchMode and IdentitiesOnly are set, keepalives run every 30 seconds, and ExitOnForwardFailure is on. If autossh is installed, the script uses it. Otherwise it falls back to plain ssh, wrapped in a detached loop that sleeps 60 seconds between retries. Because the loop is detached, closing your IDE doesn't stop it.

The macOS bug that limits damage (and why it isn't a defence)

Here's where the write-up gets interesting. On macOS, the script checks Remote Login by running systemsetup -getremotelogin without elevated privileges. It only tries to enable SSH if the output matches /Off/i. As a standard user, systemsetup prints "You need administrator access to run this tool... exiting!" and exits with status 0. That string doesn't match Off, so the enable step never runs.

The implant effectively reads "I don't have permission to check" as "SSH is already on." The result is that, on a Mac where Remote Login is off, the outbound tunnel can still connect, but traffic forwarded back through it hits a closed port 22. The inbound path is broken.

Most advice says "if SSH is off, you're safe." That's incomplete here. The authorized key and the tunnel key were still written to disk. If someone enables Remote Login later, or the machine already had it on, the backdoor works as designed. So the bug reduces the immediate blast radius on some Macs. It doesn't remove the implant, and it shouldn't change your response.

Persistence and the host reconnaissance beacon

Persistence differs by platform, and the failure modes differ too. The table below summarises what Phorion reported.

PlatformKey artifactsPersistence mechanismFailure mode noted
macOS~/.config/.smt, ~/.config/.smtk, ~/Library/LaunchAgents/com.apple.sysmond.plistUser LaunchAgent with RunAtLoad and KeepAlive set to true, loaded via launchctlsystemsetup privilege check causes the SSH enable step to be skipped
Linux~/.config/.smt, ~/.config/.smtk@reboot crontab entryCrontab check can wipe existing user cron jobs on repeat runs
Windows~/.config/smt.cmd, ~/.config/smtk, sysmon.cmd in the Startup folderScheduled task SysMon as SYSTEM, falling back to Startup folderService setup passes through a helper that hardcodes /bin/sh

The macOS LaunchAgent is the one to look for. It runs in the user context, not as a root LaunchDaemon, so it doesn't need admin rights to survive a reboot. The label is designed to look like Apple's com.apple.sysmond, which is exactly the kind of name people skim past.

The last stage is a one-off beacon. According to the write-up, it sends:

  • Hostname, username, OS platform, and architecture
  • Home directory, current working directory, and global Git email
  • Public IP, retrieved from ifconfig.me with a fallback to api.ipify.org
  • Status flags from each setup stage
  • Up to 40 environment variable names matching /KEY|TOKEN|SECRET|PASS|AWS|GCP/i

The beacon sends names, not values. Why would a developer tool need to know your Git email or which cloud variables exist? Because that inventory tells an operator which machines are worth pursuing. Any credential whose name appears on that list should be treated as potentially exposed. The report goes out as plaintext HTTP POST, which also means network monitoring may have seen it.

How to check your machines this week

Work through these steps on each developer machine, and log what you find before changing anything.

  1. Confirm the extension version. List installed extensions with versions from your editor's command line, or check the Extensions panel, and look for Claude Code at 2.1.313.
  2. Check for the planted key. Run grep svc-telemetry ~/.ssh/authorized_keys, then ssh-keygen -lf ~/.ssh/authorized_keys to get fingerprints. Compare every entry against keys you can account for.
  3. Look for persistence. On macOS, run ls ~/Library/LaunchAgents/ | grep sysmond and launchctl list | grep sysmond. On Linux, inspect your crontab for unfamiliar @reboot lines.
  4. Look for running tunnels and artifacts. Run ls -la ~/.config/.smt ~/.config/.smtk and pgrep -fl "autossh|ssh.*-R".

If any of these return matches, treat the machine as compromised and engage incident response. Here's the catch: a clean result doesn't prove a clean machine, because an attacker with access can edit or hide these artifacts. Use the checks to triage, not to clear.

When you do remediate, the order matters. Capture evidence first, then isolate the machine from the network. Remove the authorized key and the LaunchAgent only after that. Then rotate every credential whose name matched the environment variable filter, along with any tokens reachable from that Git identity. The beacon tells you what was visible. Assume the operator saw it.

  • Pull the extension from every machine, not just the ones you audited.
  • Rotate cloud and API secrets tied to any flagged host.
  • Review SSH authorized keys across your fleet, not only on suspected hosts.

Frequently Asked Questions

what is the Claude Code extension backdoor?

It's a compromised build of the official Claude Code for VS Code extension, distributed through the Cursor Marketplace in version 2.1.313. When the extension loads, hidden code plants an attacker's SSH public key, opens a reverse tunnel to an external server, sets up persistence, and sends host details to the operator. Cursor has removed the release and pulled the matching packages.

how do I know if Claude Code is compromised on my machine?

Check whether Claude Code 2.1.313 is installed, and search ~/.ssh/authorized_keys for the svc-telemetry comment. On macOS, look for a LaunchAgent named com.apple.sysmond. Any match means the machine needs incident response. A clean result is encouraging but not conclusive, since an attacker can edit these files.

why doesn't turning off SSH stop this backdoor?

The implant writes its keys and tunnel logic regardless of Remote Login state. The macOS bug only skips the step that enables SSH. If Remote Login is already on, or someone turns it on later, the planted key grants access. Treat the key and persistence as the real indicators, not the SSH setting.

should I rotate credentials after a Claude Code extension compromise?

Yes, if the machine ran the affected version. The beacon collects the names of environment variables matching KEY, TOKEN, SECRET, PASS, AWS, or GCP, so those secrets should be treated as exposed. Rotate them at the source, and also rotate any tokens tied to the Git identity on that machine.

Run the four checks above on one developer machine this week and write down what you find, even if it's nothing. That single record gives your team a baseline to compare against for the rest of the fleet. If you pass this to someone maintaining developer laptops, send them the grep svc-telemetry command first, because it's the fastest way to find out whether the Claude Code extension backdoor reached them.