{
  "question": "How do I rotate API keys and tokens after installing a malicious VS Code or Cursor extension?",
  "slug": "how-to-rotate-api-keys-and-tokens-after-a-malicious-vs-code-or-cursor-extension",
  "url": "https://www.rightshold.com/answers/how-to-rotate-api-keys-and-tokens-after-a-malicious-vs-code-or-cursor-extension",
  "short_answer": "Clean the machine first, then rotate from a different, trusted computer, then confirm the old credentials are dead. An extension runs with the editor's own permissions: VS Code's docs say the extension host can do anything VS Code can, including reading and writing files, making network requests and running processes. So treat every secret that user account could read as exposed, not only the ones the extension is known to have taken. Cursor's October 29, 2026 notice about a tampered Anthropic.claude-code 2.1.313 in its marketplace is a good example. The payload collected environment variable names (not their values), added an attacker SSH key labeled svc-telemetry and installed persistence that keeps running after you uninstall the extension. Cursor's advice ends with: rotate credentials and sessions reachable from the host, from a trusted system. Work through the credential stores on that machine, revoke rather than just replace, and check each provider's last-used data for activity you don't recognize.",
  "checklist": [
    "Check for the incident's known artifacts first. For the Cursor case, look for svc-telemetry in ~/.ssh/authorized_keys, and on Windows also in C:\\ProgramData\\ssh\\administrators_authorized_keys. Then run the publisher's remediation script or rebuild the machine. Uninstalling the extension may not remove the persistence.",
    "Isolate the machine, and do the rotation from a different computer you trust. A backdoor that is still running would see the new secrets you type or paste.",
    "List every credential the affected user account could read: ~/.ssh private keys, cloud CLI credential files (~/.aws, gcloud, Azure), ~/.npmrc and other registry tokens, the GitHub CLI and git credential helper, .env files in every workspace you opened, tokens in MCP client configs, and signed-in browser sessions.",
    "Revoke, don't only replace. A new key does nothing while the old one still works. On GitHub, revoking an OAuth app or GitHub App authorization also revokes the tokens issued under it, and a revoked token can't be restored.",
    "For AWS IAM user keys, create the new key, move your tools to it, then set the old key to Inactive and delete it. AWS's routine procedure suggests waiting days before deleting. After a compromise, deactivate at once and use get-access-key-last-used to see whether the old key was used.",
    "For npm, run npm token list, then npm token delete <id> for each token (the id, not the truncated token). npm warns that revocation can take up to an hour.",
    "Remove SSH public keys that machine used from GitHub, servers and other services, and make new key pairs on the clean machine.",
    "Sign out other sessions and review security logs, such as GitHub's security log (oauth_authorization.destroy marks a revoked token) and your cloud provider's audit trail, for the time the extension was installed."
  ],
  "sections": [
    {
      "heading": "What the Cursor notice says (Oct 29, 2026)",
      "points": [
        "Cursor says a maliciously modified Anthropic.claude-code 2.1.313, not developed by Anthropic, was in the Cursor VS Code extension Marketplace from about 2:27 AM to 1:35 PM PT on October 29, 2026 (5:27 AM to 4:35 PM ET), and that at most 5,000 users were affected.",
        "It collected hostname, username, OS, architecture, home directory path, environment variable names, working directories, configured Git email and public IP. It tried to add an attacker SSH key, enable the local SSH service and open a reverse SSH tunnel, with persistence through a LaunchAgent (com.apple.sysmond) on macOS or a scheduled task (SysMon) on Windows.",
        "Turning on the SSH service needs admin rights, which most macOS and Windows hosts didn't give it, so the attacker couldn't log in through the tunnel there. Cursor says the key, the persistence and the host report happened anyway, and the limited collection of environment variable names doesn't rule out later credential access. That's why the notice still asks you to rotate.",
        "Cursor says it has no evidence that other versions of the extension or the official distribution were affected. Third-party write-ups disagree about whether the Open VSX copy of 2.1.313 was also malicious (StepSecurity says it was distributed through Open VSX, OpenSourceMalware says the Open VSX extension is not malicious), so treat any install of 2.1.313 as suspect until you have checked."
      ]
    },
    {
      "heading": "Order matters",
      "points": [
        "Rotating first and cleaning later hands the new secrets to whatever is still running. Clean or rebuild the machine, rotate from a trusted machine, and only then put the new secrets on the cleaned one.",
        "Revoke the highest-impact credentials first: cloud admin keys, package-registry publish tokens and GitHub tokens with write access to code, because those let an attacker spread to other people.",
        "Keep notes of what you revoked and when. If a provider's logs later show the old credential being used, the timestamps tell you whether it was before or after you cut it off."
      ]
    }
  ],
  "checks": [],
  "ask_rightshold": {
    "start": "https://www.rightshold.com/start?ref=seo",
    "mcp_endpoint": "https://www.rightshold.com/mcp",
    "ask": "A Rightshold API key may have been on a machine that ran a malicious editor extension. Freeze spending, listings and new work on my account while I rotate the key.",
    "mcp_call": {
      "tool": "account_controls",
      "arguments": {
        "action": "freeze",
        "reason": "API key may have been exposed on a host that ran a malicious editor extension"
      }
    },
    "also": [
      "Needs your API key. Freeze is an emergency stop for spending, listings and new work; work already in escrow can still be finished. account_controls with action view shows your limits and today's spend, and unfreeze lifts the freeze.",
      "To rotate, create a new key with POST /v1/me/api-keys, then revoke the old one with POST /v1/me/api-keys/<key_id>/revoke. A revoked key stops working.",
      "scan_text (free) checks an extension's README or the top of its extension.js for hidden markup, invisible characters and base64 blobs before you install the next one."
    ],
    "scope": "Rightshold can freeze and rotate only Rightshold API keys. It doesn't scan your machine, see your other credentials or revoke them for you. Not legal advice."
  },
  "sources": [
    {
      "title": "Cursor: Security notice, malicious version of Anthropic.claude-code (2.1.313) in the Cursor Extension Marketplace",
      "url": "https://cursor.com/blog/claude-code-extension-security-notice"
    },
    {
      "title": "VS Code docs: Extension runtime security",
      "url": "https://code.visualstudio.com/docs/configure/extensions/extension-runtime-security"
    },
    {
      "title": "GitHub Docs: Token expiration and revocation",
      "url": "https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/token-expiration-and-revocation"
    },
    {
      "title": "GitHub Docs: Revoking your credentials",
      "url": "https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/revoking-your-credentials"
    },
    {
      "title": "AWS IAM User Guide: Update access keys",
      "url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id-credentials-access-keys-update.html"
    },
    {
      "title": "npm Docs: Revoking access tokens",
      "url": "https://docs.npmjs.com/revoking-access-tokens"
    },
    {
      "title": "StepSecurity: Trojanized Claude Code extension delivered persistent SSH backdoor",
      "url": "https://www.stepsecurity.io/blog/claude-code-extension-trojanized"
    },
    {
      "title": "OpenSourceMalware: Trojanized Claude Code extension plants an SSH backdoor",
      "url": "https://opensourcemalware.com/blog/trojanized-claude-code-extension-plants-persistent-ssh-backdoor"
    }
  ],
  "related": [
    {
      "title": "How to vet a VS Code extension before installing it",
      "url": "https://www.rightshold.com/answers/how-to-vet-a-vs-code-extension-before-installing-it"
    },
    {
      "title": "How to tell if a Claude Code or Cursor plugin is safe to install",
      "url": "https://www.rightshold.com/answers/how-to-tell-if-a-claude-code-or-cursor-plugin-is-safe-to-install"
    },
    {
      "title": "How to keep .env secrets and API keys away from AI coding agents",
      "url": "https://www.rightshold.com/answers/how-to-keep-env-secrets-and-api-keys-away-from-ai-coding-agents"
    },
    {
      "title": "How to scope OAuth tokens per task for AI agents",
      "url": "https://www.rightshold.com/answers/how-to-scope-oauth-tokens-per-task-for-ai-agents"
    }
  ],
  "computed_from": "Curated guidance; license verdicts computed from Rightshold's license profiles at render time. Not legal advice.",
  "updated": "2026-10-30"
}