A VS Code extension can be malicious, and it can compromise your workstation and cloud credentials.

  • Why it works: an extension runs in the Node.js extension host with your user account’s permissions. It is not sandboxed. It can read files, read environment variables, spawn background processes and open network connections.
  • Who is exposed: anyone who installs extensions in VS Code, Cursor, Windsurf, VSCodium or Positron. Marketplace listings and publisher badges are helpful signals, not a guarantee of safety.
  • What to do first: if you suspect an extension, uninstall it and hunt for persistence, then rotate every credential that was on that machine from a clean device.

What is VS Code extension malware?

VS Code extension malware is malicious code packaged inside an editor extension. The extension presents as a normal developer tool—a theme, a Solidity helper, a Kanban board, a UML converter or an AI assistant—and runs attacker code in the background.

Why extensions are so powerful

VS Code extensions run in the extension host, a Node.js process that starts with your editor and inherits your user permissions. An extension can:

  • read and write any file your account can reach, including .env files, SSH keys and cloud CLI credentials;
  • read environment variables, the system clipboard and the contents of your open workspace;
  • start any external program, such as curl, powershell, cscript or mshta;
  • load compiled native addons (.node files) that JavaScript static scanners cannot read;
  • open outbound network connections to any server or blockchain RPC endpoint.

An extension also controls when it runs. Setting activationEvents to * or onStartupFinished in package.json runs the extension automatically every time the editor launches.

How a clean extension turns bad

You do not have to install something obviously suspicious. Three delivery paths dominate our investigations:

  1. Impersonation. The attacker copies a trusted extension’s name, icon and README so you install the look-alike by mistake.
  2. A weaponized update. Extensions auto-update by default. Attackers often publish a harmless placeholder first to pass initial review, then push the payload in a later version—or cycle between clean, malicious and stub releases.
  3. A poisoned dependency. The extension’s own entry point looks clean, while a bundled npm dependency carries the decoded payload. See the jsononifier dropper.

What the malware does

Behavior What it means for you Example from our research
Dropper / loader Downloads and executes a second-stage binary or script. Windows installer droppers
Backdoor / implant Gives an attacker interactive remote control of your machine. SleepyDuck
Infostealer Harvests browser wallets, tokens and saved credentials. Solidity Pro
Clipboard stealer Watches the clipboard for seed phrases and swaps wallet addresses. ethdevtools
Beacon Quietly exfiltrates your username, hostname and workspace path. The oast.fun campaign
Remote code runner Polls a command server on a timer and executes returned code. Task-board RAT engine, SadiqShuaibu
Silent code exfiltration Streams open files and project context to an undisclosed server. Lolpaon.umltocode

Why forks and multiple registries matter

Microsoft restricts the Visual Studio Marketplace to official Microsoft builds of VS Code. Editors such as Cursor, Windsurf and VSCodium use Open VSX, an open registry operated by the Eclipse Foundation. The two registries verify publishers differently and enforce different checks. Yeeth Security has worked with the Eclipse Foundation to add pre-publish checks and quarantine workflows to Open VSX, and we cover the history in WhiteCobra Beginnings. Attackers actively publish to both registries.

Check a specific extension

Have an extension ID (like publisher.name) and want to know if it has already been flagged? Look it up on pkgscan.dev, our free multi-engine scanner for VS Code Marketplace, Open VSX, npm, and PyPI packages. Because pkgscan.dev tracks known malicious extensions and live scan verdicts, we do not duplicate a static blocklist on this page.

A clean result is not proof of safety. Threat actors register new publisher accounts, stage harmless placeholder versions, and rotate payloads faster than static lists update. Use a lookup as your first check, then work through the manual detection steps below. To see the exact extension IDs and hashes from campaigns our team has uncovered, browse our primary research.

How to detect a malicious extension

No single check is enough. Work through these four steps.

Step 1: List what is installed

Run the command for your editor. --show-versions adds the version number.

code --list-extensions --show-versions      # VS Code
cursor --list-extensions --show-versions    # Cursor
codium --list-extensions --show-versions    # VSCodium

By default, extensions are stored on disk in these per-user folders (unless overridden with --extensions-dir or the VSCODE_EXTENSIONS environment variable). You can open them and read the files.

Editor Windows macOS / Linux
VS Code %USERPROFILE%\.vscode\extensions ~/.vscode/extensions
Cursor %USERPROFILE%\.cursor\extensions ~/.cursor/extensions
VSCodium %USERPROFILE%\.vscode-oss\extensions ~/.vscode-oss/extensions

Remove anything you do not recognize or no longer use. Every extension is attack surface.

Step 2: Check the publisher

Before you install, and when you audit, ask these questions:

  • What does the verification badge actually mean? On the Visual Studio Marketplace, a blue check mark next to a domain means the publisher proved domain ownership, the domain is at least six months old, and the publisher has at least six months of good standing. On Open VSX, a shield icon means the publisher claimed ownership of the namespace on GitHub. Both are useful signals, but neither means a human audited the code.
  • Is the name an exact match? Impersonators use look-alike IDs and display names. We have seen juanbanco, jaunblanco and luanblanco copy the real Solidity extension from juanblanco. The display names used zero-width spaces and a right-to-left override character so they rendered as “Juan Blanco”. Read the October 22 report and the language-pack-sol follow-up.
  • Is the account new? A publisher created today with one extension and few installs is a red flag. Also treat download and install counters with caution, as they can be inflated.
  • Does the repository exist? Open the linked repo. Check that it is real, active and matches the published code. In our task-board RAT investigation, all eight extensions linked to GitHub repositories that returned 404.
  • Does the size make sense? A small utility that weighs tens or hundreds of megabytes is hiding something. One sample shipped a 205 MB video concealing a compiled implant; another packed a 29.7 MB nested VSIX inside a language pack.

Step 3: Read the manifest and look for native or nested files

A .vsix file is a zip archive. Open package.json inside it, or in the installed folder. Look for:

  • activationEvents set to * or onStartupFinished. The code runs on every launch without waiting for a user command.
  • contributes.mcpServers entries that run a local command. See this MCP install prompt.
  • extensionPack or extensionDependencies entries that pull in other extensions you did not ask for. See PackRat.
  • npm dependencies you do not recognize. The payload may be in a dependency.
  • Bundled .node, .exe, .dll, .msi, .bat or nested .vsix / .payload archives.

Find bundled binaries and nested packages across all installed extensions:

# Windows PowerShell: list binaries or nested packages inside installed extensions
Get-ChildItem "$env:USERPROFILE\.vscode\extensions" -Recurse -Include *.node,*.exe,*.dll,*.msi,*.bat,*.vsix,*.payload |
  Select-Object FullName, Length
# macOS / Linux: same idea
find ~/.vscode/extensions -type f \( -name "*.node" -o -name "*.exe" -o -name "*.dll" -o -name "*.msi" -o -name "*.vsix" -o -name "*.payload" \)

Many legitimate extensions ship native files too. Treat a hit as a reason to look closer, not as proof.

Step 4: Watch for signs of compromise

These behaviors point to a malicious extension that has already run:

  • Hidden child processes right after the editor starts. Look for cscript, mshta, curl, or powershell -WindowStyle Hidden with the IDE as the parent. See the Windows installer dropper family.
  • Unexpected network calls on launch or on every keystroke. This includes DNS lookups with long encoded subdomains (the oast.fun beacon) and inline completion providers that send your code to raw IPs with rejectUnauthorized: false (Lolpaon.umltocode).
  • The editor silently installs another extension. Watch for CLI calls to --install-extension --force from a temp file (DigitalBarberTrim) or internal calls to workbench.extensions.command.installFromVSIX (language-pack-sol).
  • New remote-access software you did not install. One campaign silently installed a legitimate ScreenConnect client.
  • New Windows startup entries or Defender exclusions that appeared after an extension install.
  • A scheduled or repeating poll. A timer that polls a command server every few seconds (task-board RAT engine) or fetches JavaScript every few minutes (SadiqShuaibu).

If you find any of these, go straight to removal.

How to remove malware from VS Code

Deleting the extension is only the first step. Many malicious extensions are droppers. They start another program, and that program stays after the extension is gone.

Step 1: Note what you have

Write down the extension ID, the version and the time you installed it. You will need the time later to check logs. If you have a security team, zip the extension folder before you delete it so they can analyze it.

Step 2: Uninstall it everywhere

Close the editor. Then uninstall from the command line, and repeat for each editor you use:

code --uninstall-extension publisher.name
cursor --uninstall-extension publisher.name
codium --uninstall-extension publisher.name

Then check the extensions folder from Step 1 of detection and delete any leftover folder with that name. Also check for extra extensions installed at the same time: some loaders pivot across VS Code, Cursor, Windsurf, Positron and VSCodium at once, or install a second nested VSIX under a legitimate publisher’s ID (such as a fake juanblanco.solidity 0.0.3 or 0.0.4). If the extension registered an MCP server, run MCP: List Servers from the Command Palette and check your mcp.json file to remove it.

Step 3: Hunt for what it left behind

Look for anything that survives a restart.

Windows

  • Run keys: HKCU\Software\Microsoft\Windows\CurrentVersion\Run and HKLM\...\Run.
  • Scheduled tasks and the Startup folder.
  • New files in %LOCALAPPDATA% and %TEMP%, especially .exe, .bat, .ps1, .msi and .dll files.
  • Defender exclusions: Get-MpPreference | Select-Object ExclusionPath.
  • Remote-access tools you did not install, such as ScreenConnect.

macOS

  • ~/Library/LaunchAgents and /Library/LaunchAgents.
  • Login Items in System Settings.

Linux

  • User services: systemctl --user list-units --type=service, plus ~/.config/systemd/user.
  • crontab -l and hidden folders in your home directory.

For real examples, our GlassWorm Solana report lists a Windows Run key and a hidden backup folder. The SleepyDuck report lists a systemd unit, a macOS LaunchAgent and a ScreenConnect install.

Step 4: Decide if the machine is trusted

  • The extension only beaconed (sent system names and nothing else): rotate secrets and monitor.
  • A second-stage payload ran, or a backdoor was installed: assume full compromise. Reimage the machine. Do not try to clean it by hand.
  • You cannot tell: treat it as compromised.

Step 5: Rotate credentials

Do this from a clean device, not the affected machine. A stolen session token works even after you change a password.

  1. Cloud and CI tokens (AWS, GCP, Azure, GitHub Actions secrets).
  2. GitHub and GitLab personal access tokens, and SSH keys.
  3. Package registry tokens (npm, PyPI, crates.io).
  4. Any secret in .env files or in your shell environment.
  5. Browser sessions and saved passwords. Sign out everywhere.
  6. Crypto wallets. Move funds to a new wallet with a new seed phrase. Seed phrases cannot be rotated.

Then check audit logs for activity after the install time you wrote down in Step 1.

Step 6: Report it

Report the listing so the registry can remove it and blocklist it for other users:

  • Visual Studio Marketplace: open the extension’s Marketplace web page, scroll to the More Info section, and click Report a concern. When Microsoft verifies a malicious extension, it removes the listing and adds it to VS Code’s blocklist, which automatically uninstalls it on affected machines.
  • Open VSX: email security@open-vsx.org with the extension ID, version numbers, observed behavior and indicators (per the Open VSX Security Policy).

In a company, search your endpoint tools for the extension ID across the fleet and add the ID to your blocklist immediately.

How malicious extensions bypass security

Registries and scanners look for bad code. Attackers have learned what they look for. These are the techniques we see most. Each links to the investigation behind it.

Delayed and repeating execution

A scanner that runs the extension for a few seconds sees nothing. So some extensions wait.

  • ethdevtools waited five days before it began reading the clipboard every 30 seconds. Read the report.
  • DevFlow extensions waited five minutes, then fetched JavaScript over plain HTTP and ran it with new Function. Read the report.
  • SadiqShuaibu extensions re-ran a remote script every ten minutes. Read the report.

Payloads hidden in dependencies

Reading the extension’s own code is no longer enough. In ascii-fetcher, almost all of the code lived in an npm dependency. That package decoded a hidden Windows command and ran it after anti-analysis checks. Read the report.

Impersonation and namespace flooding

  • Evil twins. We found 28 counterfeit Open VSX extensions across twelve impersonated namespaces. Read the report.
  • Look-alike publishers. Homoglyphs, invisible characters and a right-to-left override made fake Solidity publishers look real. Read the report.
  • Account floods. 174 new publishers appeared on Open VSX within hours. Read the report.

Command execution through the operating system

The extension does not need clever code. It can ask Windows to fetch and run a file. We documented droppers using curl, cscript, mshta, PowerShell irm | iex and npm postinstall scripts. Read the report. One extension even used a VS Code MCP install prompt that did not show the user what it would install. Read the report.

Payloads hidden where scanners do not look

  • Native binaries. A Rust implant shipped as a .node addon, outside the reach of JavaScript analysis. Read the report.
  • Images, databases and WebAssembly. One cluster hid commands in PNG pixels, SQLite files, WASM sections and more across 26 builds. Read the report.
  • A video file. A compiled four-platform implant hid inside a 205 MB MP4. Read the report.

Command channels on public infrastructure

Blocking a bad domain does not help when the instructions live on a blockchain. GlassWorm read its next stage from Solana. Read the report.

Version cycling, placeholder staging and nested VSIX installs

Attackers publish a clean or empty placeholder version first to pass initial review, then push the weaponized build as an update.

  • DigitalBarberTrim alternated between clean, malicious and 43-byte stub releases while using a side-car i.js loader to install a remote VSIX across six editors. Read the report.
  • The task-board RAT cluster shipped tiny placeholder builds across six of eight listings before updating them into a five-second polling backdoor. Read the report.
  • SleepyDuck’s Marketplace waves served a backdoor for only seventeen minutes on one listing (read the report), and then used workbench.extensions.command.installFromVSIX to silently install a nested VSIX under the real juanblanco.solidity publisher ID (read the report).

Attacks on the scanner itself

Some extensions now embed fake system instructions aimed at AI-powered reviewers. The goal is to make the scanner approve the extension. Read the report.

How to protect your IDE

Use the built-in editor and marketplace protections

  • Understand what your registry checks. On the Visual Studio Marketplace, Microsoft scans new uploads and updates with multiple antivirus engines, runs packages in a sandboxed clean-room VM, checks package signatures on install, and removes blocklisted extensions automatically. On Open VSX (used by Cursor, Windsurf and VSCodium), the Eclipse Foundation runs automated pre-publish checks and quarantine workflows developed with Yeeth Security. Neither registry catches every delayed or staged attack, so treat marketplace checks as the first filter, not the last.
  • Pay attention to publisher trust prompts. Starting in VS Code 1.97, installing an extension from an untrusted third-party publisher triggers a confirmation dialog. You can review and revoke trusted publishers at any time with the Extensions: Manage Trusted Extensions Publishers command.
  • Keep Workspace Trust enabled. VS Code’s Workspace Trust (security.workspace.trust.enabled) opens unfamiliar folders in Restricted Mode so tasks and untrusted workspace extensions do not run automatically.
  • Install less, and keep updates flowing. Each extension is code you trust with your credentials, so install as few as you can justify. Keep automatic extension updates on, though. Publishers ship fixes for vulnerable extensions, and an extension that never updates keeps its bugs. The risk that dominates right now is not an unpatched extension — it is a compromised or impostor publisher pushing a malicious version. The cooldown below is the control for that.
  • Add an update cooldown. Since VS Code 1.125 you can delay how long a newly published extension version must exist before it auto-installs, using extensions.autoUpdateDelay (in hours, default 2). This is the extension-ecosystem version of npm’s minimumReleaseAge: it buys the registry and the community time to catch a malicious release before it reaches your machine. A cooldown is a precaution, not a control, so pick the number from your own threat analysis — we suggest 3 days (72) as a starting point for most teams, longer where developer machines hold production credentials. Cursor exposes the equivalent as extensions.installCooldownHours per user, or fleet-wide as Marketplace Install Cooldown (hours) in team settings.

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

    Two mechanical caveats. The delay applies to auto-updates only — a fresh install from the marketplace UI or code --install-extension still lands immediately, so treat first installs as a separate review decision. And updates from trusted publishers such as Microsoft, GitHub and OpenAI skip the delay, so this narrows the window for third-party publishers, it does not remove it.

    Do not simply switch updates off. Some guidance says to set "extensions.autoUpdate": "off" and approve every new version by hand. That closes the window almost completely, and a few organizations should do it — but understand what you are buying. Publishers release patches for vulnerable extensions, so a frozen fleet keeps known bugs, and every security fix now waits in your review queue. Given where the risk sits today, with malicious and hijacked releases far more common than exploited extension vulnerabilities, a cooldown is the better default. If your machines hold production credentials or you are a high-value target, decide deliberately: weigh explicit version approval against the security workload it creates, and document the reasoning so the next person can revisit it rather than quietly flipping the setting during an incident.

Enforce policy across a team

Individual habits do not scale. Use controls your IT or security team owns:

  • Allow-list extensions (extensions.allowed / AllowedExtensions). Starting in VS Code 1.96, administrators can restrict which extensions users can install and enable using the extensions.allowed application setting or the AllowedExtensions group/MDM policy (which overrides user settings). Once configured, any extension that does not match an allow rule is blocked, and already-installed blocked extensions are disabled. You can allow by publisher ID, full extension ID, "stable" only, or exact pinned versions:

    {
      "extensions.allowed": {
        "microsoft": true,
        "github": true,
        "redhat": "stable",
        "dbaeumer.vscode-eslint": ["3.0.0"]
      }
    }
    

    Note one documented limitation: for locally installed .vsix files, VS Code matches against the identifier declared inside the package without verifying its origin. Pair allow-listing with monitoring for local VSIX installs.

  • Control which editors are allowed. Unmanaged editors and forks bypass your VS Code group policy unless you manage their configurations as well.
  • Enforce the cooldown centrally. extensions.autoUpdate and extensions.autoUpdateDelay are both manageable through VS Code enterprise policies, so a cooldown you decide on applies fleet-wide instead of depending on each developer’s settings. Document the value you chose and why, and revisit it when your exposure changes — a cooldown that nobody can explain gets switched off during the first incident.
  • Add endpoint and network rules. Alert when an editor spawns cscript, mshta, hidden PowerShell or curl, writes new startup items, or contacts webhook relays, raw IPs, or unexpected GitHub release assets.
  • Limit what a stolen session can reach. Use short-lived SSO/OIDC credentials instead of long-lived .env tokens. Keep production secrets off developer laptops, and use dev containers or remote workspaces for untrusted repos.
  • Host a private marketplace or internal mirror. Organizations on GitHub Enterprise can run VS Code’s Private Marketplace to curate and rehost vetted extensions.

Our CISO guide to IDE security goes deeper on policy and risk.

Optional: DevGuard detection

Yeeth builds DevGuard, an extension that brings scan results into your editor. It warns you about risky extensions where you decide to install them. It uses verdicts from Argus, the scanning platform we run on new extension uploads.

DevGuard is one layer. It does not replace allow-listing, endpoint monitoring or credential hygiene. If your team wants help designing those controls, contact us.

Latest VS Code malware research

The examples on this page come from original investigations by the Yeeth Security research team. We monitor extension uploads in real time, reverse-engineer malicious payloads, and report confirmed findings to registry maintainers. In 2026 the Eclipse Foundation added Yeeth Security to the Open VSX Security Hall of Fame as a Security Guardian.

Date Category Investigation

Frequently asked questions

Can a VS Code extension contain malware or steal credentials?

Yes. VS Code extensions run in the Node.js extension host with your user account's full permissions. A malicious extension can read .env files, SSH keys, cloud CLI credentials, and browser data, monitor your clipboard, and spawn background processes.

How do I check if my VS Code extensions are safe?

List every installed extension with code --list-extensions --show-versions, look up unfamiliar IDs on pkgscan.dev, verify the publisher's domain and repository link, and inspect package.json for startup activation (* or onStartupFinished), bundled binaries (.node, .exe, .dll, .msi), or nested .vsix archives.

Does uninstalling a malicious VS Code extension remove the malware?

Not always. Many malicious extensions act as droppers that install a second-stage backdoor, register a Windows Run key, macOS LaunchAgent, or Linux systemd user service, or silently install remote-access software such as ScreenConnect. You must check for persistence and rotate exposed credentials from a clean device.

Are Cursor, Windsurf, and VSCodium affected by VS Code extension malware?

Yes. They use the same VSIX extension format and Node.js extension host architecture, and pull from the Open VSX registry by default. Multi-IDE droppers we have analyzed specifically target VS Code, Cursor, Windsurf, VSCodium, and Positron at the same time.

Can I delay VS Code extension updates to avoid malicious releases?

Yes. VS Code 1.125 added extensions.autoUpdateDelay, which sets how many hours a newly published version must exist before it auto-installs (default 2; administrators can enforce it by policy). We suggest 72 (3 days) as a precaution, but the right value comes from your own threat analysis. The delay applies to auto-updates only, not fresh installs, and extensions from trusted publishers skip it. Cursor offers the equivalent through extensions.installCooldownHours or a fleet-wide Marketplace Install Cooldown. Prefer a delay over switching updates off: publishers ship patches for vulnerable extensions, and today the larger risk is a malicious or hijacked release, not an exploited extension bug. Explicit version approval closes the window further but adds real security workload, so make that call deliberately.