TL;DR If you run the Claude Code extension in Cursor or another editor that installs from Open VSX, run
grep svc-telemetry ~/.ssh/authorized_keys. If it prints a line, your machine installed the trojanized 2.1.313: run Cursor's cleanup script and rotate your credentials from another computer. Seeing 2.1.314 installed today proves nothing.
Version 2.1.313 of anthropic.claude-code, published on October 29, shipped a malicious loader inside its extension.js. The editor loading the extension is enough, with no prompt sent. It appends an attacker's SSH key to your authorized_keys, installs its own autostart, and sends details about your machine to an outside server. That autostart lives outside the extension folder, so updating to 2.1.314, or uninstalling, leaves it in place.
Anthropic didn't publish it. The package repackaged the official extension under the legitimate publisher name, and how it got into the registry hasn't been established yet.
Who could have received it
It was available for about eleven hours, from 2:27 to 13:35 PT (09:27 to 20:35 UTC) on October 29. By the channel your editor installs extensions from:
| Where you install the extension | Did it serve 2.1.313? |
|---|---|
| Cursor (its marketplace mirrors Open VSX) | Yes. Cursor puts it at 5,000 users at most |
| VSCodium, Windsurf, Gitpod and other Open VSX editors | Yes, if they updated inside the window |
| VS Code with Microsoft's marketplace | No evidence it did; today it lists 2.1.312, then jumps to 2.1.314 |
The CLI (claude in your terminal) |
No: the CLI never had a 2.1.313, the changelog goes from 2.1.312 to 2.1.314 |
The extension auto-updates, so whatever your extensions list shows today isn't evidence either way. What counts is what the payload left on disk.
What it leaves on your machine
Analyzed by StepSecurity and Cursor in the macOS (Apple Silicon) and Windows x64 packages; the code also carries a Linux branch:
| System | What it leaves |
|---|---|
| All | An ssh-ed25519 ... svc-telemetry key at the end of ~/.ssh/authorized_keys, and a private key at $TMPDIR/.stk_ followed by 10 hex characters |
| macOS | ~/.config/.smt, ~/.config/.smtk, and the LaunchAgent ~/Library/LaunchAgents/com.apple.sysmond.plist, named to pass for one of Apple's |
| Windows | %USERPROFILE%\.config\smt.cmd, the scheduled task SysMon or, when it can't create one, sysmon.cmd in the Startup folder |
| Linux | An @reboot line in your crontab that runs ~/.config/.smt |
It also tries to switch on the local SSH server and open a reverse tunnel to 134.209.82.225, retrying every 60 seconds. Turning on local SSH needs admin rights, which the extension doesn't have on most Macs and PCs, so on those the tunnel fails. The key, the autostart and the data upload work regardless. The attacker's server is already offline.
Check it in a minute
On macOS or Linux, paste this block into a terminal. Each line looks for one of the traces in the table and prints nothing when it finds none:
ls -d ~/.*/extensions/anthropic.claude-code-2.1.313-* 2>/dev/null
grep -lF svc-telemetry ~/.*/extensions/anthropic.claude-code-*/extension.js 2>/dev/null
grep -nF svc-telemetry ~/.ssh/authorized_keys 2>/dev/null
ls ~/.config/.smt ~/.config/.smtk ~/Library/LaunchAgents/com.apple.sysmond.plist "${TMPDIR:-/tmp}"/.stk_* 2>/dev/null
crontab -l 2>/dev/null | grep -F .smt
pgrep -fl '\.stk_|\.config/\.smt'
A clean machine prints nothing. This is the output in a test home with the traces recreated as empty files and a sample key, run on Linux:
/Users/dev/.cursor/extensions/anthropic.claude-code-2.1.313-darwin-arm64
/Users/dev/.cursor/extensions/anthropic.claude-code-2.1.313-darwin-arm64/extension.js
1:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEXAMPLEonlyEXAMPLEonlyEXAMPLEonlyEXAMPLE dev@laptopssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdvylCEJ/k2TpezcTfedrkHyFSK9IZ3vmP6vhY4Ss0P svc-telemetry
/Users/dev/.config/.smt
/Users/dev/.config/.smtk
/Users/dev/Library/LaunchAgents/com.apple.sysmond.plist
/var/folders/x7/T/.stk_3f9a1c07be
Look at the third line. The payload appends its key without a newline before it, so it can end up glued to your last real key on the same line. If you clean it by hand, cut only the stretch that ends in svc-telemetry, never the whole line.
On Windows, Cursor's check 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" }
If something shows up
1. Run the cleanup script for your system
Cursor publishes remediate-macos.sh and remediate-windows.ps1. They remove the infected extension folders (found by content, not by version number), the autostart, the dropped files, the tunnel processes and the key, and exit with an error if anything is left.
# macOS: as your own user, not with sudo
bash remediate-macos.sh
# Windows: close every editor first; PowerShell as Administrator
powershell -ExecutionPolicy Bypass -File .\remediate-windows.ps1
On macOS, if it ends with note: something listens on localhost:22, you already had local SSH on (Remote Login, for example), and the tunnel could have exposed your machine. Linux has no script: remove the crontab line with crontab -e, the files in the table and the key's stretch, and kill the processes pgrep listed.
2. Rotate your credentials from another computer
The payload sent the names of your environment variables containing KEY, TOKEN, SECRET, PASS, AWS or GCP, your git email and your public IP. Not the values, but a map of what to go after. Rotate the GitHub, CI, cloud, package registry tokens and SSH keys used from that machine, working from one you know is clean. If the tunnel did connect, StepSecurity recommends rebuilding the machine.
3. Run the check again
Run the check block again: it should finish without a single line. If you use the extension in VS Code, the native panel tip covers how it differs from the CLI in your terminal, which wasn't affected.
Sources: Cursor's security notice · StepSecurity's analysis
Official docs: Use Claude Code in VS Code