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".
path-is-absolute inside its
bundled node_modules. Its banner.png "wasn't
an image file. Instead, it is an archive containing two malicious
binaries" — one run through the cmstp.exe living-off-the-land
binary, the other a Rust trojan. Nothing was downloaded at install;
the dependency was pre-packaged. The same post counts detections of
malicious software on the Marketplace at 27 in 2024 and 105 in the
first ten months of 2025.whensunset.chatgpt-china (1,340,869 installs) and
zhukunpeng.chat-moss (151,751), both working as
advertised while hidden code read every opened file, Base64-encoded
it and posted it to a server in China; a server-triggered mode
exfiltrated up to fifty workspace files per command. Figures as
quoted from Koi by BleepingComputer and The Hacker News on 23–26
January 2026: every Koi write-up has redirected to Palo Alto
Networks since the acquisition closed on 14 April 2026, so the
primary could not be re-read.suspublisher18.susvsex, description "Just testing": on
activation it zipped, uploaded and AES-encrypted a test folder,
polled a private GitHub repository for commands with an embedded
token, and shipped two AI-generated decryptors. Microsoft removed it
on 6 November..vsix
from a GitHub release and installs it into VS Code, Cursor, Windsurf
and VSCodium; six were confirmed malicious at publication. The
example pair is MS-CEINTL.vscode-language-pack-tr
(Microsoft, 1.1 million installs) against
Emotionkyoseparate.turkish-language-pack. All 73 were on
Open VSX, as were the 72 Socket found in March delivered
through extensionPack dependencies. The original
GlassWorm (Koi, October 2025) hid its loader in invisible Unicode
variation selectors and read its command server from Solana
transaction memos; the Eclipse Foundation's own account (27 October
2025) puts the reported download count at 35,800 and the incident
closed on 21 October.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:
| Listing | Source | Verdict | Why |
|---|---|---|---|
| malkolm.theme-artschool-remake and 18 siblings | ReversingLabs, Dec 2025 | not assessable | the gallery returns no record — removed by Microsoft; a MED finding, action warn, never a pass |
| whensunset.chatgpt-china · zhukunpeng.chat-moss | Koi, Jan 2026 | not assessable | removed; the same MED, warn |
| suspublisher18.susvsex | Secure Annex, Nov 2025 | not assessable | removed 6 November 2025 |
| 17 further listings, six reports | ReversingLabs, Datadog, Checkmarx, Kaspersky/Koi, Secure Annex, Yeeth | not assessable | every one removed by the time it was measured |
| MS-CEINTL.vscode-language-pack-tr | control — the extension GlassWorm v2 cloned | PASS 100 | domain-verified publisher, signed, validated, source declared |
| equinusocio.vsc-material-theme | control — pulled by Microsoft in February 2025 by mistake, restored in March | PASS 100 | 4.3 million installs; the "obfuscated code" was a bundled SDK |
| 7finney.ethcode | control — compromised by a pull request in June 2025, repaired in 0.5.1 | PASS 100 | the repaired listing, as published |
| juanblanco.solidity | control — the extension the Open VSX fake outranked | PASS 100 | 1.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.
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.
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.
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.
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.
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.