Malicious VS Code Extensions

Four published campaigns · roster measured 18 September 2026

What this is. Four research teams have separately published malicious extensions for VS Code: ReversingLabs found 19 with a trojan hidden inside a bundled dependency (December 2025), Koi Security found two AI-chat extensions with 1.5 million installs quietly copying every file a developer opened (January 2026), Secure Annex found a vibe-coded ransomware test uploaded as an extension (November 2025), and Socket has tracked the GlassWorm family through 2026 — 73 sleeper clones of popular extensions in April alone. This page states what our 17-check roster (V1–V17) finds against the named exemplars from those reports, its false-positive rate on the 100 most-installed extensions, and the one thing the measurement made plain first: on the Microsoft Marketplace every named exemplar has already been removed, and the live volume of this campaign family is on Open VSX, a registry this roster does not assess. Neither number below is a guarantee — see "What this doesn't mean".

The four campaigns

What the roster catches, alone

Run without the campaign blocklist below — the roster's own signals only, against the Marketplace's live gallery on 18 September 2026 — on every Microsoft-Marketplace identifier the primary write-ups name (ReversingLabs' nineteen, MaliciousCorgi's two, susvsex, the three ahban ransomware listings, Datadog's three MUT-9332 Solidity extensions, Checkmarx's solid281, three WhiteCobra listings, four GlassWorm listings from Secure Annex's November table, and Yeeth's four Solidity Pro stealers from August 2026 — 40 in all), plus four controls:

ListingSourceVerdictWhy
malkolm.theme-artschool-remake and 18 siblingsReversingLabs, Dec 2025not assessablethe gallery returns no record — removed by Microsoft; a MED finding, action warn, never a pass
whensunset.chatgpt-china · zhukunpeng.chat-mossKoi, Jan 2026not assessableremoved; the same MED, warn
suspublisher18.susvsexSecure Annex, Nov 2025not assessableremoved 6 November 2025
17 further listings, six reportsReversingLabs, Datadog, Checkmarx, Kaspersky/Koi, Secure Annex, Yeethnot assessableevery one removed by the time it was measured
MS-CEINTL.vscode-language-pack-trcontrol — the extension GlassWorm v2 clonedPASS 100domain-verified publisher, signed, validated, source declared
equinusocio.vsc-material-themecontrol — pulled by Microsoft in February 2025 by mistake, restored in MarchPASS 1004.3 million installs; the "obfuscated code" was a bundled SDK
7finney.ethcodecontrol — compromised by a pull request in June 2025, repaired in 0.5.1PASS 100the repaired listing, as published
juanblanco.soliditycontrol — the extension the Open VSX fake outrankedPASS 1001.8 million installs, eleven years old

Read plainly: on the Microsoft Marketplace, every published exemplar was removed after disclosure and before we looked, so the roster meets each one as "not assessable" — which is a REVIEW-level finding with the action warn, and never a pass. There is no still-live exemplar on the Microsoft side to score. The four controls — a cloned victim, a wrongly-pulled-then-restored theme, a repaired compromise and an outranked original — all pass, which is the shape a roster should have before anyone trusts its warnings.

What actually blocks these, in the product

All 40 listings above, and the 24 single-purpose publishers behind them, are named entries in RepoGates' campaign blocklist (platform: vsx; confidence: confirmed where the identifier is in a primary source we could read, suspected where it is quoted from one we could not) — the layer that runs ahead of the roster and an account's own allowlist. That matters for a removed listing because of something ReversingLabs documented in August 2025: the name of a removed extension can be re-registered by anyone. An entry here denies the re-registered name before the roster is consulted, and an extension whose declared source repository is listed is CRIT on V5. The roster table above is what the checks alone found; this list is the product's actual behaviour on these names.

What the roster would have seen — and would not

Stated as inference, because the listings are gone. Every named Microsoft-side exemplar was published under a publisher created for it, with no verified domain and no declared source repository, and declared that it runs code — the shape V1, V2, V5 and V7 escalate on a listing under 90 days old, and the shape none of the 100 most-installed extensions has. That is provenance, not proof. What the roster would NOT have seen is the payload itself. ReversingLabs' trojan was a PNG inside a dependency folder — a file list shows a PNG, and V12 says plainly that it lists what executes inside a package without reading it. MaliciousCorgi's exfiltration lived in the extension's JavaScript, which this tier does not read. GlassWorm's loader hid in invisible Unicode inside JavaScript, not inside the agent rule files V14 reads. Reading the bundle is a deep scan, which is decided and not started for extensions; until it exists, a PASS here means the provenance and the declared surface show none of what these checks look for, never that the code was inspected.

False positives on the top 100

Run against the 100 most-installed extensions on the Marketplace (18 September 2026, locally through the same code that answers /v1/vsx/score): 0 BLOCK, 1 REVIEW, 99 PASS, no partial scans, every package's file list read, 1.1 seconds median. The one REVIEW is abusaidm.html-snippets: an established listing whose publisher has no verified domain and which declares no source repository — nothing ties the package to anyone, and the roster says so at MED.

The first run of the same day said 87 PASS, 13 REVIEW, and all thirteen were legitimate extensions caught by rules aimed at the wrong thing. Four — Live Server, Code Runner, Live Share, indent-rainbow — ship unbundled dependencies whose node_modules carry playwright's, applicationinsights' and mpg123's build helpers, and V12 was treating any executable there as the ReversingLabs hiding place, which it cannot recognise anyway. Four — GitHub Copilot, Claude Code, ChatGPT and one more — declare no source repository because they are closed source by design; V5 now treats that as a note for a domain-verified publisher. Five — prettier, vscode-icons, Markdown Preview Enhanced and Microsoft's own CMake Tools and Makefile Tools — ship a CLAUDE.md, an AGENTS.md or an .mcp.json inside the package, and V13 was scoring that as it scores a repository; an installed extension's directory is never the workspace an agent opens, so it is now a note, and the files are still read. Those three gradings, and the reason for each, are in the check pages; the numbers above are from the run after them.

Open VSX

GlassWorm v2's 73 clones, the 72 extensions Socket found delivered through pack dependencies in March 2026, the sleepers that activated in March, and the fake "Solidity Language" behind a US$500,000 theft in July 2025 were all on Open VSX — the registry VSCodium, Cursor and Windsurf install from. RepoGates does not assess it. A code --install-extension line or a Marketplace URL is assessed against the Microsoft record; an Open VSX URL comes back "ask", by name, rather than a guess against a listing that may be a different package under the same id. Open VSX is decided and not started on the roadmap.

What this doesn't mean

The Marketplace validates and signs every extension it publishes, and every campaign above passed that validation; V6 and V11 read it as necessary, never as sufficient. An extension that scores PASS today was checked today, on its publisher, its listing, its declared surface and the file list of its package — never a claim that its JavaScript is benign, never a claim about the version it auto-updates to tomorrow, and never a claim about a listing installed from the editor's own UI, which no hook and no preflight sees.