Supply Chain Attacks

VS Code Marketplace Malware Campaigns in 2025

A senior engineer's review of the 2025 VS Code Marketplace malware wave, including typosquats, trojanized themes, and extensions that stole npm tokens at scale.

Shadab Khan
Security Engineer
7 min read

The VS Code Marketplace has, for years, been the softest target in the developer toolchain. It is popular enough to guarantee distribution, lightly moderated by industry standards, and it runs arbitrary Node.js code on the developer's machine with broad filesystem access. 2025 is the year attackers fully industrialized that combination. Multiple research teams documented hundreds of malicious extensions uploaded in single campaigns, with a noticeable shift from proof-of-concept uploads to deliberately monetized developer machine compromise.

How large was the 2025 VS Code Marketplace malware problem?

Research published throughout 2025 by Koi Security, ExtensionTotal, and others tracked hundreds of malicious extensions published in identifiable campaigns, with individual campaigns pushing 40 to 100 extensions at a time. A single mid-2025 wave documented by ExtensionTotal involved extensions impersonating popular themes, Prettier forks, and language packs, several of which accumulated tens of thousands of installs before takedown.

The absolute number is less important than the scale relative to previous years. The marketplace had isolated malicious extensions every year since 2019, but the pattern in 2025 became campaign-driven. Attackers uploaded families of extensions in bursts, watched which ones got installs, doubled down on naming patterns that worked, and rotated to new publisher accounts when old ones were taken down. The extensions were ephemeral, but the playbook was persistent.

Microsoft's response accelerated during the year, including stricter publisher verification, faster takedowns, and new signing requirements for extensions. These are real improvements. They are also reactive, which means the attacker sets the tempo.

What tactics defined the typosquat wave?

The 2025 typosquat wave targeted three categories. First, popular themes, because theme extensions rarely get code review from users and often get installed on first impression. Second, formatter and linter extensions, because developers install them across many repos and they persist in user settings. Third, AI assistant extensions, because the market was hot, new legitimate tools launched weekly, and users could not easily distinguish them.

The naming tactics were consistent. Attackers added one character, swapped letters, used zero-width Unicode, or inserted vendor prefixes that looked official (ms-, azure-, vscode-). The marketplace search algorithm at times surfaced typosquats above the legitimate extension when install counts were briefly inflated through fake reviews and stars. This briefly-inflated-then-removed pattern was effective because it worked during the narrow window when a developer was actively searching.

The payloads in this wave were typically staged. The initial extension downloaded a second-stage binary at install or first-activation time from a CDN or GitHub release, which made static scanning of the VSIX package itself nearly useless. Only runtime behavior revealed the malicious activity.

Why were trojanized themes so effective in 2025?

Themes are trusted because developers assume a theme only changes colors. That assumption is wrong. A VS Code theme is a standard extension with a package.json, a JavaScript entry point, and the same API access as any other extension. A theme can read your workspace, exfiltrate files, spawn child processes, and access secrets in your environment.

Several 2025 trojanized themes exploited exactly this gap. They presented as legitimate-looking Dracula or Solarized forks, shipped actual theme JSON, and also included activation hooks that scanned for .env files, .npmrc, ~/.aws/credentials, and browser storage. One campaign documented by researchers in Q2 2025 targeted specifically the Solana and Ethereum wallet extensions installed in the same VS Code profile, exfiltrating private keys that developers had cached during testing.

The lesson from the theme wave is that extension categories are not security categories. "Theme" and "snippet pack" sound passive, but the runtime gives them the same power as any full development tool. Treat every extension as a full-trust install, because that is what it is.

How did extensions become a pipeline into npm and PyPI compromise?

The sharpest connection in 2025 was between VS Code extension compromise and maintainer account takeover on registries. An infected extension running on a maintainer's machine had access to .npmrc, to cached PYPI_TOKEN, to the system keychain in some cases, and to browser session cookies for npmjs.com, pypi.org, and github.com. One stolen token let the attacker publish a malicious version of the maintainer's package to the public registry.

This chained attack was not theoretical. Several 2025 npm takeover incidents traced back to developer machines infected through VS Code extensions. The chain was short: install a trojanized theme, lose your npm token within hours, and wake up to a malicious version of your own package published to the registry. For single-maintainer packages, that timeline gave defenders almost no window to respond.

The mitigation is to treat extension installation as a privileged action. Use separate VS Code profiles for publishing work, never store long-lived publish tokens on the same machine you install extensions on, and rotate tokens aggressively.

What signals actually detect malicious extensions today?

Static signals are weak because payloads stage at runtime. Useful signals are behavioral: extensions that make network requests to non-approved destinations, extensions that read files outside the workspace, extensions that spawn child processes, and extensions that modify user or workspace settings to persist after uninstall. The Koi Security and ExtensionTotal feeds both publish continuously updated indicators based on this kind of runtime telemetry.

Publisher signals help but are not sufficient. A new publisher account is suspicious. A publisher with only one extension is suspicious. A publisher who recently changed ownership is suspicious. Microsoft rolled out verified publishers with stronger identity requirements during 2025, which raises the bar for abuse but does not eliminate it, because verification tells you who uploaded something, not what it does.

The strongest signal, and the one that matters for senior engineers, is dependency graph behavior. An extension is a package, and its npm dependencies have the same supply chain risk as any other Node.js dependency. Scan the extension as you would scan any other package that will run with full user privileges on a developer machine.

What should engineering organizations actually do about this?

Four controls cover most of the exposure. First, maintain an internal allowlist of approved VS Code extensions and enforce it through Group Policy or MDM. The allowlist is the single highest-leverage control. Second, separate developer environments from publishing environments, and never install extensions on the machine that holds publish tokens. Third, scan extensions before they are added to the allowlist, using both the VSIX contents and the extension's transitive npm dependency tree. Fourth, monitor installed extensions for updates that materially change behavior, because legitimate extensions have been sold to attackers and repurposed, a pattern documented multiple times in 2025.

Organizations with an allowlist in 2025 had almost no exposure to the campaigns described above. Organizations without one took casualties every month.

An underappreciated addition is treating the Marketplace as a procurement surface rather than an app store. Developer tooling that runs with user privilege on an engineer's machine is enterprise software, regardless of how it is delivered, and it deserves the same review as any other enterprise software purchase. A short internal review document per approved extension, covering publisher identity, dependency graph, and observed behavior, is cheap to produce and dramatically improves the quality of approval decisions.

How Safeguard.sh Helps

Safeguard.sh treats VS Code extensions as what they actually are: full-trust packages with an npm dependency graph that ships to developer machines. Our AI-BOM inventories extension dependencies end-to-end, and Griffin AI flags behavioral divergence when an update introduces new network destinations, filesystem access, or child processes. We apply 100-level depth reachability analysis to extension dependencies so a staged second-stage payload hiding four layers deep is surfaced before install, and Lino compliance enforces your internal allowlist policy across developer workstations. For the token-theft chain specifically, our pickle detection and model signing/attestation capabilities extend to credential artifacts on developer machines, and container self-healing ensures that if a malicious extension makes it to a build environment, the rollback is automatic. The net result is that a marketplace campaign stops being a weekly triage problem.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.