On 13 August 2026 Bloom Security published research it calls Extension Resurrection. Some extension packs on the VS Code Marketplace and Open VSX list extensions that do not exist anymore. An attacker who registers one of those missing names can publish an extension that installs through the trusted pack, with no extra consent from the developer. Bloom calls the dangling references "Shadow Dependencies."
Both marketplaces have since added protections. The pattern still matters because it works the way package typosquatting and abandoned names do, in a place most teams do not inventory.
What's affected
- VS Code Marketplace: 677 of 4,179 extension packs had at least one shadow dependency.
- Open VSX: 94 of 321 packs had at least one.
- The vulnerable packs total more than 500,000 downloads.
- Editors that use these marketplaces include VS Code, Cursor, Kiro, Windsurf, Antigravity, VSCodium and Eclipse Theia, according to Bloom.
Extensions run with Node.js host access. They can read and write files, start child processes and make network requests. Packs do not pin their bundled extensions to specific versions, so a pack installed years ago can pull in a newly published extension on update.
Vendor response
Bloom reported to the Eclipse Foundation (Open VSX) on 5 February 2026. The foundation protected at-risk namespaces and added checks for nonexistent extensions and dependencies. Bloom reported to Microsoft on 17 February 2026. Microsoft first rated it Moderate, then reopened the case after more evidence. Per the reporting, protections were staged, with user-action protections completed in June 2026.
How to check if you're exposed
List what each developer and build image actually has installed:
code --list-extensions --show-versions
code --list-extensions | wc -l
Then, for each pack (ids that bundle other extensions), look at the "Extension Pack" tab in the editor or the extensionPack field in its manifest, and confirm every referenced id resolves to an extension that exists and belongs to the publisher you expect.
What to do now
- Inventory installed extensions across developer machines and dev containers. Most teams cannot answer what is installed.
- Remove packs you do not use, and install individual extensions you do need by exact id.
- Turn off auto-update for extensions in locked-down environments, or use an internal allowlist.
- Treat a past trust decision as temporary. Review what your editors can install without a new approval.
How this could have been avoided
- Marketplaces should reject nonexistent references at publish time and hold freed namespaces. Bloom says both now check for this.
- Packs that bundle extensions should pin them to publishers and versions, so a new owner of a freed name cannot join in.
- Allowlists on managed editors let you restrict installs to extension ids you have reviewed.
- Keep extension inventory in your asset list. Dangling names are invisible if nobody lists them.
Quick check
Why does a Shadow Dependency need no action from the developer?
The trust decision was made when the developer installed the pack. Packs do not pin their parts, so a newly published extension under a freed name installs through the pack.
What can an extension do once installed?
It runs with Node.js host access, so it can read and write files, spawn processes and reach the network.