How to Find Malicious VS Code, Cursor and Chrome Extensions in 2026
Inventory extensions per OS, hunt the Cursor backdoor by its key and files, then allowlist VS Code versions and Chrome extension IDs. Read 4 Nov 2026.

Start with an inventory, not a blocklist. Find where each editor and browser keeps its extensions, list what is installed with versions, then check the Cursor backdoor's indicators. VS Code can allowlist exact versions, Chrome's ExtensionSettings policy blocks extensions by ID, and Chrome Enterprise Core is listed at $0 on Google's page.
Cyberpresso data: Between 18 August and 4 November 2026, Cyberpresso published 256 news posts. Four covered extensions caught misbehaving in the wild: a Twitch helper that leaked OAuth tokens, 31 fake Chrome VPN extensions, GlassWorm's VS Code themes, and the Claude Code copy on Cursor's marketplace. Four more covered flaws in extensions, plugins or editors: BragJack, the VS Code Workspace Trust flaw, Plugin4Shell in AI coding agents, and the embedded browsers in Codex and VS Code. Every version and indicator comes from the vendor's own page.
Where each editor and browser keeps its extensions
Start with the folders on disk. Visual Studio Code's extension docs put installed extensions in one per-user folder on every operating system, and the docs say you can move that folder with a command-line option or the VSCODE_EXTENSIONS variable.
Chromium's user data directory page puts all user data in one directory, and each profile is a subfolder, often named Default. The page does not name the extension subfolder, so for Chrome, inventory through the policy and reporting tools below rather than by file path. Cursor's docs do not name an extension folder either, so this page gives no Cursor path.
| Editor or browser | macOS | Windows | Linux |
|---|---|---|---|
| Visual Studio Code | ~/.vscode/extensions | %USERPROFILE%\.vscode\extensions | ~/.vscode/extensions |
| Cursor | Not documented on the pages read | Not documented on the pages read | Not documented on the pages read |
| Chrome user data directory | ~/Library/Application Support/Google/Chrome | %LOCALAPPDATA%\Google\Chrome\User Data | ~/.config/google-chrome |
How to list what is installed
Visual Studio Code's command-line reference documents a flag that prints every installed extension with its version. Run it on each machine, then compare the output with the indicators in the next section.
code --list-extensions --show-versions
For the browser, Google's Chrome Enterprise Core page prices the product at $0 and says its cloud management adds no cost, and it describes reports on extension use and security events across the company. For Cursor, the docs read here name no list command, so use the indicator checks below on each endpoint. Cursor's deployment page says MDM can enforce policies for extensions and names Jamf and Intune as examples, so a managed fleet can run the same checks through its MDM tool. The best MDM software ranking covers the options.
How to hunt for the Cursor Claude Code backdoor
Cursor's security notice, dated 29 October 2026 and updated on 30 October, names versions 2.1.312 and 2.1.313 of the Anthropic.claude-code extension for Windows and macOS. It says the builds were not developed by Anthropic, and that they were available from about 2:27 am to 1:35 pm Pacific on 29 October. Cyberpresso covered the incident in its news post on the Cursor marketplace copy.
The malicious code tries to add an attacker's key to the SSH authorized keys, open a reverse tunnel, and keep that tunnel alive through a LaunchAgent on macOS or a scheduled task on Windows. The table below turns the notice's indicators into checks. The notice treats a host as impacted when the svc-telemetry key is found, and then the remediation steps apply, not only a removed extension. A version match alone makes a host suspect, so check for the key next.
| Indicator | Where it appears | How to check |
|---|---|---|
| Extension build | Anthropic.claude-code 2.1.312 or 2.1.313 | Treat the host as suspect, then check for the key |
| Key comment | svc-telemetry in the SSH authorized keys | The grep or Select-String commands below; a key hit means impacted |
| Key fingerprint | SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk | Compare with each key in authorized_keys |
| macOS persistence | LaunchAgent ~/Library/LaunchAgents/com.apple.sysmond.plist, label com.apple.sysmond | List the plist file |
| Windows persistence | Scheduled task SysMon, with a Startup fallback named sysmon.cmd | Query the task by name |
| Linux persistence | A cron @reboot line that runs ~/.config/.smt | List the crontab |
| Dropped files | ~/.config/.smt, ~/.config/.smtk, $TMPDIR/.stk_ followed by 10 hex characters on macOS, %USERPROFILE%\.config\smt.cmd on Windows | List the files with the commands below |
| Network | Reverse SSH to 134[.]209[.]82[.]225 on TCP 22, and an HTTP POST beacon to port 8099 | Look for connections to that address on any port |
| Processes | ssh -N -R and autossh -M 0 | Search the process list |
The address is defanged, so remove the brackets before you search.
| Package or file | SHA-256 |
|---|---|
| 2.1.312, darwin-arm64 VSIX | fcbb327e38e61c4fec795e0d0591f52cd1014b813d20a5912104953c3a17c364 |
| 2.1.312, win32-x64 VSIX | 3de1722901165769893bef57c72594e9a54459faa23f3091b136b79966edd081 |
| 2.1.313, darwin-arm64 VSIX | 80402fdcad8799285fd93044976973ca000da7995fb93363f819bb8e4f84ee6c |
| 2.1.313, win32-x64 VSIX | 6786ec90cbd45949695bd7805c9fbb26cfc91bc5fc897de0183d9bcb9cb21731 |
| Payload, extension.js | ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15 |
The commands below run the checks. The Linux block is a precaution: the notice lists Linux paths but no Linux builds.
On macOS, run these as the affected user:
grep -qs svc-telemetry ~/.ssh/authorized_keys && echo "svc-telemetry key found" || echo "No key found; machine not impacted"
ls -l ~/Library/LaunchAgents/com.apple.sysmond.plist ~/.config/.smt ~/.config/.smtk 2>/dev/null
ls -l "${TMPDIR%/}"/.stk_* 2>/dev/null
ps aux | grep -E "ssh -N -R|autossh -M 0" | grep -v grep
lsof -nP [email protected]
On Linux, as a precaution:
grep -s svc-telemetry ~/.ssh/authorized_keys
ls -l ~/.config/.smt ~/.config/.smtk /tmp/.stk_* 2>/dev/null
crontab -l 2>/dev/null | grep "\.config/\.smt"
On Windows, 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" }
schtasks /query /tn SysMon
Test-Path "$HOME\.config\smt.cmd"
Get-NetTCPConnection -RemoteAddress 134.209.82.225 -ErrorAction SilentlyContinue
If any check hits, the notice's steps apply. Isolate the host, remove the unauthorized key, the persistence entries and any running tunnel processes, then decide whether to rebuild it. Rotate the credentials and sessions that the host could reach, and do the rotation from a clean system. The notice warns that uninstalling the extension may not be enough, because the payload drops standalone persistence scripts that keep running. It attaches a macOS script, which runs as the affected user and not as root, and a Windows script, which runs as administrator. This page does not copy them, so read them before you run anything.
How to allowlist extensions in VS Code
VS Code's extensions.allowed setting is documented in its enterprise docs from version 1.96. With no value set, every extension is allowed. With a value set, any extension that matches no rule is blocked, and an installed extension that you block is disabled.
A key without a period is a publisher ID, and a key with a period is a full extension ID. Ranges are not supported, so list each approved version. The enterprise docs give this example, which pins one extension to one version:
"extensions.allowed": {
"dbaeumer.vscode-eslint": ["3.0.0"]
}
Under that rule, every other version is blocked, including a bad release. The notice describes Cursor's marketplace rather than Microsoft's, so treat this as the pattern for a VS Code fleet, not as a fix for the Cursor case. An administrator can set the same rules with the AllowedExtensions policy, which overrides the user's setting on managed devices. A syntax error in that policy value means the setting is not applied at all, so check the Window log after each rollout.
How to allowlist extensions in Cursor
Cursor documents an AllowedExtensions policy. The table maps it to a setting named extensions.allowed, the same name as VS Code's setting, but Cursor's page describes boolean values only. The policy takes a JSON object whose keys are publisher names or full extension IDs, with true or false as values, and a specific ID overrides its publisher. Cursor's own example is {"anysphere": true, "github": true}.
Cursor's page does not say whether version lists work, so version support is undocumented rather than absent. The nearest controls are publisher and ID rules and the ExtensionGalleryServiceUrl policy, which sets a custom marketplace URL. A true value for a publisher admits every extension from that publisher, and the notice says the bad builds were published as Anthropic.claude-code without being developed by Anthropic. A publisher rule for Anthropic would therefore have let them install. Cursor's UpdateMode policy can set updates to none, but the page describes it as automatic update behavior and does not say it covers extensions.
How to block and pin extensions in Chrome
Chrome's ExtensionSettings policy sets, per extension ID, how a browser may install it. Google's Help Center how-to page on Chrome policies says it overrides ExtensionInstallBlocklist, ExtensionInstallAllowlist and ExtensionInstallForcelist policies, along with two others. The installation modes are allowed, blocked, force_installed and normal_installed, and allowed is the default when nothing is set.
On Windows, the policy takes one line of JSON through Group Policy. Google's example goes further: it force-installs Google Docs Offline and Google Keep, lets users disable Keep but not Docs Offline, allows Google Calendar and blocks everything else. This is the same pattern in minimal form:
{"*":{"installation_mode":"blocked"},"gmbgaklkmjakoegficnlkhebmhkjfich":{"installation_mode":"allowed"}}
The key * is the default for every extension, and the ID key is the exception. The case for this is the 31 fake VPN extensions, which all ran one codebase behind separate listings. Cyberpresso covered them in its Chrome VPN extensions post. A default block stops a new listing. It does not stop a listed extension from changing, which is where pinning comes in. Setting override_update_url to true makes Chrome use the update_url in the policy rather than the URL in the extension's manifest, and Google's Help Center page calls this pinning. The limit is in Chromium's ExtensionSettings policy definition: the flag is ignored when update_url is a Chrome Web Store URL. Pinning therefore needs a self-hosted update URL that serves the packed extension as a .crx file, as the same Help Center page describes.
How to delay or stop extension auto-update
In VS Code, extensions.autoUpdate controls automatic updates, and the Extensions view has a command to disable them. The extensions.autoUpdateDelay setting waits a number of hours after a release before installing it. Its default is 12 hours, and 0 installs at once. The delay applies only while auto-update is on. Administrators can set both through the ExtensionsAutoUpdate and ExtensionsAutoUpdateDelay policies, and that page gives the reason for the delay: it helps avoid installing a problematic update right after release. The docs describe the delay for updates to installed extensions and say the Update button skips it. They do not say whether a fresh install waits, so this page does not claim either way.
{
"extensions.autoUpdateDelay": 12
}
Cursor's notice says nothing on marketplace update timing, so no Cursor update setting appears here. For scale, the notice's window ran about 11 hours from the first bad build to its removal, which is less than VS Code's 12-hour default delay. That arithmetic is ours and covers VS Code's feed only.
What an allowlist does not stop
An allowlist judges the extension, not what the extension can reach, and that limits every control above.
- A trusted publisher's bad build. A publisher rule admits every build from that publisher until someone changes the rule. A version list stops a new bad build. A curated private marketplace is another control: VS Code's enterprise docs describe a private marketplace with an allow list, though that marketplace is currently available to GitHub Enterprise customers. Cursor's
ExtensionGalleryServiceUrlpolicy points machines at a custom marketplace or mirror. - Local packages. The VS Code enterprise docs say rules for a locally supplied VSIX use the identifiers declared inside the package, and that they do not verify the package's origin or limit its runtime permissions.
- Runtime access. The VS Code extension docs say extensions have the same permissions as VS Code itself. An allowlist decides what installs, not what runs afterwards.
- Paths that are not extensions. The embedded-browser flaws in Codex and VS Code sit outside any extension list.
- Removal as cleanup. The notice says uninstalling may leave standalone persistence scripts running, so the allowlist does not clean a host that already has the build. Rotated credentials need a second factor behind them, as in the 2FA rollout guide.
Version pinning and, in VS Code, a delay work together for a trusted publisher. A pin holds the approved version, and a delay gives time for a takedown before a fleet installs a release. The BragJack demonstration, which Cyberpresso covered as a lab result, not an attack seen in the wild, is a reminder that an extension with only two common permissions can still reach built-in AI assistants.
FAQ
How do you find a malicious VS Code extension on one machine?
Run code --list-extensions --show-versions, then look for Anthropic.claude-code among the builds named in the hunt table above. Next check the SSH authorized keys for the comment svc-telemetry, and check for the macOS LaunchAgent com.apple.sysmond.plist or the Windows scheduled task SysMon. A version match makes the host suspect. The notice counts a host as impacted when the key is found, and then the remediation steps apply, not only an uninstall.
Was the Claude Code extension on Cursor's marketplace malicious?
Cursor's notice says two builds of Anthropic.claude-code were malicious on Windows and macOS, and that they were not developed by Anthropic. They were live in the marketplace for roughly 11 hours on 29 October 2026, from about 2:27 am Pacific until 1:35 pm.
Does Chrome Enterprise Core cost money to use for extension control?
Google's Chrome Enterprise Core page lists the product at $0 and says its cloud management has no extra charge. Core is the cloud tool for Chrome policies, settings and extensions, and it includes extension reports. It says data loss prevention and zero-trust access cost extra under Chrome Enterprise Premium, so check that tier before you assume a feature is in Core.
Can a VS Code allowlist stop a bad update from a trusted publisher?
A version list does. A publisher rule such as "github": true admits every release from that publisher, while a version list, written as ["3.0.0"] in the docs example, blocks any new release until someone adds it. Ranges are not supported, so each version is listed by hand. A curated private marketplace with an allow list is another control, though VS Code's is currently available to GitHub Enterprise customers.
Can Cursor pin extension versions the same way?
Cursor's page does not document version lists, so version pinning is undocumented there rather than absent. Its AllowedExtensions policy takes booleans for publishers or extension IDs. Use those rules, a custom marketplace through ExtensionGalleryServiceUrl, and the indicator checks on each endpoint.
What is the default auto-update delay in VS Code?
VS Code's documented default is 12 hours. Setting extensions.autoUpdateDelay to 0 installs updates as soon as they are published, and the delay only applies while automatic updates are on. Administrators can set the value through the ExtensionsAutoUpdateDelay policy. The delay setting is documented here only for VS Code, and this page names no Chrome equivalent. The docs do not say whether a fresh install waits, so do not assume it does.
Is an allowlist enough to protect a browser fleet?
No. An allowlist covers installed extensions only. The embedded-browser flaws in Codex and VS Code are not extensions at all, and Cyberpresso's post on them describes both as unpatched at the time. Pair the Chrome policy with the endpoint checks, and review what each approved extension can reach.
How we checked this page
Every version, path, setting, hash and price was read on the vendor's own page on 4 November 2026: Cursor's security notice and deployment docs, the VS Code extension, command-line, enterprise and policy docs, Chromium's user data directory page, Chromium's ExtensionSettings policy definition, Google's Help Center how-to page on Chrome policies, and the Chrome Enterprise Core page. The Cyberpresso count covers every news post between 18 August and 4 November 2026 whose title or description names an extension, theme, plugin, marketplace or VS Code. Posts where the word does not mean an extension or editor add-on were left out, such as a PostgreSQL server plugin, a criminal "marketplace" and a passkey-themed story. WordPress server plugins and PHP packages are left out too.
Louis Corneloup, founder of Toolradar and Dupple, is the author. How products are described is on how we rate, and corrections sit in the editorial policy.
Cite this: Cyberpresso, "How to Find Malicious VS Code, Cursor and Chrome Extensions in 2026", November 2026.
New extension and package compromises reach the Cyberpresso daily brief before they reach a monthly checklist.
Some offers on this page may be paid placements or contain affiliate links.
Cyberpresso: daily cyber & AI brief
Free daily newsletter, read in 5 minutes.
Subscribe free