1
0 Comments

How Bloom Security's Extension Resurrection Attack Works on Open VSX and VS Code Marketplace

The version number was the whole trick.

Bloom Security's researchers had already found the door. What they needed was proof it opened, and the marketplace itself told them how. When they tried to publish an extension into a namespace that a trusted extension pack was pointing at, Open VSX rejected the upload because a record for that exact version already existed in its index. The extension had never been published. The index believed otherwise. Incrementing the version by one satisfied the pack's dependency and put attacker-controlled code inside a bundle with a legitimate reputation.

That sequence sits at the center of Extension Resurrection, the vulnerability Bloom Security disclosed across Open VSX and the Visual Studio Code Marketplace. It reached 750-plus extension packs and more than 500,000 downloads. Both marketplaces have since patched.

Start With How Identity Works

Every extension carries a two-part identity. On the VS Code Marketplace the format is <publisher>.<extension_id>. On Open VSX it is <namespace>.<extension_id>. Different words, identical concept: who published it, and what they published.

That structure is supposed to be the safeguard. Resurrecting a removed extension is not merely a matter of registering an available ID. The attacker also needs the original publisher or namespace. Bloom Security's finding is that acquiring one was trivial on both platforms, because namespaces and publishers were freely registerable regardless of whether existing software already referenced them.

No account compromise. No credential theft. Claim an unclaimed name and publish into it.

Where the Phantom References Come From

Bloom Security uses the term Shadow Dependency for a pointer inside a trusted bundle aimed at an extension that does not exist on the marketplace.

Two paths create one. Mirroring is the first. Open VSX exists as a vendor-neutral marketplace under the Eclipse Foundation because Microsoft's VS Code Marketplace terms explicitly forbid non-Microsoft products from connecting to it, which would otherwise leave VSCodium, Eclipse Theia, Cursor, Windsurf, Kiro, and Antigravity without a first-party source. Not every extension gets mirrored across. When a pack makes the trip and one of its bundled components does not, the reference survives while the target does not.

Deletion is the second path, and it is simpler. An extension referenced by a live pack is removed. The pack keeps pointing.

The Scan

Bloom Security ran a scanner across both marketplaces, comparing every pack manifest against the actual existence of what it bundled.

Open VSX returned 94 of 321 extension packs holding at least one shadow dependency whose namespace was unregistered. The VS Code Marketplace returned 677 of 4,179 packs with at least one shadow dependency, 60 of them belonging to a publisher nobody had registered.

Two targets were selected for a live test. On Open VSX: prettify-json in the mohsen1 namespace. On the VS Code Marketplace: control-snippets under the svipas publisher. Each was bundled by a pre-existing pack. Neither existed on its marketplace.

Why Version Pinning Matters Here, and Why There Is None

Extension packs reference their contents by ID only. They do not pin versions.

That is a deliberate design choice rather than an oversight. Part of the value proposition of a pack is centralized management of a set of extensions, and requiring individual version-by-version updates would defeat the purpose.

The consequence is that any version satisfies the reference. When Bloom Security published a bumped version of the resurrected extension, the pack's bundled link resolved to it almost immediately. A user installing the original pack through Open VSX receives that extension as part of the curated set. No separate prompt appears. No additional click is required.

Auto-update compounds the reach. Bundled extensions inherit their auto-update configuration from the pack, and the default has auto-updates enabled. Anyone who installed the pack at any point in the past under default settings can receive the resurrected extension on a routine update cycle.

The Payload Runs Unsandboxed

Extensions for VS Code and its compatible IDEs execute with Node.js host access. File reads and writes, child process spawning, and outbound network requests are all in scope. Bloom Security is direct about the implication: an extension is not sandboxed in any meaningful sense from a code execution standpoint, so installing a malicious one is functionally remote code execution on the developer's machine.

The targeting profile is what makes the math uncomfortable. Victims are almost exclusively software developers, meaning access to source repositories, cloud credentials, deployment pipelines, and internal tooling. Working from the aggregate half-million downloads and assuming a very conservative 50 percent auto-update rate, the research puts a quarter of a million developer endpoints in reach inside 24 hours.

The blog states it plainly:

"The attacker doesn't need to phish a developer, compromise a registry, or publish a convincing fake. The trusted bundle does the social engineering. The phantom namespace does the rest."

Root Cause Is Two Gaps, Not One

Bloom Security separates the failure into distinct components.

Neither marketplace enforced extension existence at pack creation. Packs referencing extensions that had never been created were accepted, published, and mirrored. The dependency check that should have blocked them was absent. Bloom Security identifies this as the root cause.

Namespace registration was open. Names referenced by live software were available to anyone, which turned the first gap into an exploitable one.

Open VSX carried an additional wrinkle. During triage, the team found that extension dependencies, meaning extensions declaring other extensions in their manifests, were vulnerable in exactly the same way.

Fixes and Their Timing

Eclipse Foundation received the report on February 5, 2026, and moved within hours, assigning every at-risk namespace to the open-vsx account so nobody could register them. It then committed to blocking creation of packs with non-existent bundled extensions and extensions with non-existent dependencies. That pre-publication check is live and enforced.

Microsoft received the report on February 17, 2026, with a proof of concept and video. MSRC initially scored it Moderate, citing existing publisher resurrection prevention. Bloom Security disputed that, and Microsoft reopened the case. The engineering response confirmed a partial October fix and stated that "The extension resurrection prevention has been in effect for admin actions since October, and for user actions since this month." The full timeline runs from October 2025 for admin actions to June 2026 for user actions, documented at github.com/microsoft/vsmarketplace/discussions/1708.

For marketplace operators, Bloom Security's prescription is two checks: validate that bundled extensions and declared dependencies exist at submission time, and protect namespaces referenced in published packs from open registration. Phantom pointers in a package index are not a data hygiene problem. They are attack surface.

on August 13, 2026