Trusted code is one bad update away from malware

PhotoStructure

7 min read Original article ↗

Trusted code is one bad update away from malware

What just happened

On October 29, 2026, a malicious anthropic.claude-code 2.1.313 package was available through the Cursor Extension Marketplace, approximately 2:27 a.m. to 1:35 p.m. Pacific (09:27–20:35 UTC). Cursor says it removed the package, restored its marketplace, and had the attacker’s server taken offline. Its notice reports no evidence that other versions or the official distribution were affected. This wasn’t every Claude Code installation or every marketplace. Cursor’s incident notice.

The payload tried to add an attacker’s SSH login key, enable the SSH server, and open an outbound tunnel that forwarded connections back to the workstation’s SSH port. It installed startup scripts to retry the tunnel and sent a host-information report, including environment variable names, to an external server. Permission failures and bugs could prevent SSH service setup without preventing key installation, persistence, or transmission of host information. Phorion’s technical analysis.

Read-only detection

Start with Cursor’s published check for the svc-telemetry SSH key. Our read-only detector also checks extension files, startup entries, and live connections. An indicator warrants investigation; no findings do not prove a machine is clean. An installed version or cached package alone doesn’t prove the payload ran.

Download the pinned script, save it as claude_code_compromise_check.py, and inspect it. Use the command for your platform below to verify its SHA-256 matches this value before running it with Python 3.8+:

73d96647e17bbf0dbd1e9cd5a0f5cfce6af626346a09d82e8b90ab599d3f7b6d

From the download directory, verify the hash:

On macOS:

shasum -a 256 claude_code_compromise_check.py

On Linux:

sha256sum claude_code_compromise_check.py

On Windows, use PowerShell:

Get-FileHash .\claude_code_compromise_check.py -Algorithm SHA256

If it matches, run python3 claude_code_compromise_check.py on macOS/Linux or py -3 claude_code_compromise_check.py on Windows.

Exit code 2 means an indicator was found: investigate the finding. 1 means no indicator was found but a check was incomplete; inspect each item under CHECKS INCOMPLETE, with administrator help if needed. 0 means no listed indicator was found in the locations checked. It checks the current user and present state. Other accounts, custom installation locations, and historical activity need separate investigation.

What the workstation and fleet checks look for

The detector checks installed extensions and cached VSIX packages for version 2.1.313, embedded package and bundle hashes, and the paired extension.js markers 134.209.82.225 and svc-telemetry. Version-only matches outside Cursor are reported separately because the source is unverified. Its pinned source lists the exact hashes and locations.

The pinned script’s macOS VSIX hash differs from Cursor’s current notice. Also compare preserved packages against the notice; the script’s version and bundle-marker checks still apply.

It checks ~/.ssh/authorized_keys, plus C:\ProgramData\ssh\administrators_authorized_keys on Windows, for the comment and this unauthorized key fingerprint:

SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk

Persistence checks cover:

  • macOS: ~/.config/.smt, ~/.config/.smtk, and ~/Library/LaunchAgents/com.apple.sysmond.plist.
  • Linux: ~/.config/.smt, ~/.config/.smtk, and matching user cron entries. These are payload implementation details reported by Phorion, not evidence of a separate affected Linux marketplace package.
  • Windows: %USERPROFILE%\.config\smt.cmd, %USERPROFILE%\.config\smtk, the SysMon scheduled task, and %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\sysmon.cmd.

It also looks for temporary .stk_<10 hex> tunnel-key files, suspicious SSH processes, and live connections to the incident IP. A filename or task name needs inspection of its contents or action; it isn’t conclusive on its own. Artifact analysis.

For LAN and fleet checks, search retained firewall, proxy, flow, and endpoint telemetry for 134.209.82.225, especially outbound SSH on TCP 22 and HTTP POST /beacon on TCP 8099. Correlate matches with extension installations and changes to SSH keys or startup entries. Search from the exposure window onward: persistence can outlast installation.

A LAN sensor cannot see the reported 127.0.0.1:8099 loopback attempt; that needs endpoint visibility. Public-IP services ifconfig.me and api.ipify.org are legitimate. Contact with them alone isn’t evidence of compromise. Network indicators.

This has happened before

Cursor reports no evidence that the official Claude Code distribution was affected. But this isn’t the first malicious editor extension, and it certainly won’t be the last.

In February 2026, Aqua disclosed malicious Trivy extension 1.8.12 on Open VSX, designed to use a local AI coding agent to steal sensitive information. Its advisory confirms the malicious release, but doesn’t establish automatic delivery. Aqua’s advisory.

On May 18, 2026, malicious Nx Console 18.95.0 reached the Visual Studio Marketplace and Open VSX. It harvested credentials; CISA confirmed automatic updates delivered the malicious version and linked the compromise to theft of GitHub’s own internal repositories. Nx’s postmortem, CISA’s alert.

Microsoft introduced an automatic-update delay in VS Code 1.123 on June 3, describing it as protection against problematic or compromised releases. That predates the October Cursor incident; the release notes don’t attribute the change to these specific attacks. VS Code release notes.

Reduce the risk next time

Give new extensions and updates time

Keep fewer extensions. Inventory their IDs, versions, and marketplace sources; approve what your team needs. Check publisher identity and package integrity, but don’t treat a badge or a matching publisher name as a safety guarantee. VS Code supports managed allowlists by extension and version. Cursor documents its own extension allowlist and optional signature verification; configure those separately. Extension security, VS Code enterprise controls.

For VS Code, set a 24-hour automatic-update delay in settings JSON:

{
  "extensions.autoUpdate": "on",
  "extensions.autoUpdateDelay": 24
}

Manual updates bypass VS Code’s delay. Update settings.

For Cursor, individuals can set "extensions.installCooldownHours": 24. Administrators can enforce Team settings → Security & automation → Marketplace Install Cooldown. A team cooldown overrides individual settings. Cursor’s extension documentation.

Cooldowns are a crude workaround. VS Code exempts certain “trusted” publishers, including Microsoft, GitHub, and (somewhat surprisingly) OpenAI, from cooldowns. Early adopters still bear the risk, and malware that goes undetected longer than the waiting period can still reach you. The delay buys time; use it alongside restricted permissions, limited credentials, and network controls.

Teams should stage updates in isolated test environments. Delays postpone legitimate fixes too, so document an emergency-update process.

Limit what your editor can reach

Run editors without administrator privileges, and avoid unrestricted passwordless sudo for development accounts. VS Code extensions inherit the editor’s permissions, including file access and process execution. Ordinary user permissions still expose your files and credentials. Extension runtime permissions.

Disable the SSH server if you don’t use it. Keep the host firewall enabled, restrict necessary inbound access, and monitor changes to authorized_keys and startup mechanisms. With no SSH service listening, this payload’s tunnel has no SSH login service to reach; that doesn’t prevent its other actions.

Run the editor and its extensions inside a separate development VM with limited credentials and host access. A remote workspace alone can leave extensions running locally. Avoid sharing your whole home directory or forwarding a broadly privileged SSH agent into the VM. Where VS Code extensions run.

Control outbound traffic and local access

Restrict outbound SSH from developer machines to approved destinations. Account for Git-over-SSH, remote development, and administration before enforcing the rule. Blocking the reported SSH destination would have interrupted this tunnel; blocking its IP or external TCP 8099 traffic would have interrupted the external report. Keep these as incident-specific indicators, not permanent guarantees.

An inbound-only router firewall doesn’t stop a connection initiated by your workstation. DNS filtering doesn’t stop a connection to a literal IP address either. Retain connection logs and apply controls at both internet and internal network boundaries. CIS network monitoring guidance, NIST SP 800-53, SC-7.

Separate developer machines from sensitive local devices, backup storage, and administrative interfaces, permitting only required traffic between them. Segmentation limits what a compromised workstation can reach; it doesn’t prevent extension execution. CISA’s segmentation guidance.

Respond to a finding

Investigate reported indicators. If you find evidence of execution or backdoor installation, isolate the workstation, preserve useful logs and artifacts, then follow Cursor’s remediation instructions. Download and inspect its macOS script or Windows script. Run the macOS script as the affected user, not root; use elevated PowerShell on Windows and the exact command in the notice. Linux requires platform-specific cleanup. Uninstalling alone can leave standalone persistence running. Assess whether to rebuild, then rotate accessible credentials and revoke sessions from a trusted device.