Back to BlogSecurity

Nx Console 18.95.0 Is the VS Code Supply-Chain Wake-Up Call JavaScript Teams Needed

The Nx Console 18.95.0 compromise turned a trusted VS Code extension into a credential stealer and helped expose GitHub’s internal repos. Here are the practical checks JavaScript teams should add now.

vscodenxgithubsupply-chainjavascriptci
Nx Console 18.95.0 Is the VS Code Supply-Chain Wake-Up Call JavaScript Teams Needed

Nx Console 18.95.0 Is the VS Code Supply-Chain Wake-Up Call JavaScript Teams Needed

This week’s Nx Console postmortem is the kind of security story that should make every JavaScript team re-check what “trusted tooling” actually means.

GitHub said on May 20 that an employee device was compromised through a poisoned VS Code extension, and that the attacker’s claim of access to roughly 3,800 GitHub-internal repositories was broadly consistent with its investigation. Then Nx published the ugly part on May 21: the poisoned extension was Nx Console version 18.95.0, and the compromise chain started a week earlier when a contributor machine pulled a malicious @tanstack/* package during a routine pnpm install.

That matters because this was not just “npm malware happened again.” This was a straight line from package compromise to editor compromise to repo compromise. If your team lives in VS Code, Cursor, GitHub Actions, and gh, this is your threat model now.

Relevant reading:

What actually happened

The short version is bad enough:

  • A malicious @tanstack/zod-adapter package landed during the May 11 TanStack incident.

  • An Nx contributor machine installed it during pnpm install.

  • The malware stole credentials, including a GitHub CLI OAuth token.

  • On May 18, the attacker used that access to publish a poisoned Nx Console 18.95.0 to the Visual Studio Marketplace and Open VSX.

  • Nx says anyone who had auto-update enabled during the exposure window should treat their machine as compromised.

The detail that really stuck with me is that the extension was live briefly, but that was enough. Nx says Microsoft telemetry showed 28 installs, Open VSX showed 41 downloads, but Nx’s own activation telemetry suggested the real affected count may have been much higher. That is exactly why “it was only up for a few minutes” is not a serious defense.

Also worth noticing: the malware wasn’t narrowly targeted at one token. Nx says it harvested GitHub tokens, SSH keys, .env files, cloud credentials, Vault tokens, npm tokens, and more. In other words, a compromised dev box is still the fastest way to turn one mistake into a full-stack incident.

The practical lesson: stop treating editor extensions like harmless UI candy

A lot of teams still treat VS Code extensions like theme packs with better marketing. That is obviously not the world we live in anymore.

The most useful reaction is not “ban extensions.” That usually turns into shadow IT in about two days. The useful reaction is to make extension trust explicit and narrow.

Here are the four checks I’d add right now.

1. Build an extension allowlist, not an extension free-for-all

If an extension can read your workspace, run on activation, auto-update, and touch local credentials, it is part of your supply chain.

At minimum, make a short internal allowlist for extensions that developers actually need. Include publisher name, extension ID, and who approved it. For high-privilege extensions that interact with monorepos, GitHub, cloud tooling, or secrets, require a second look before adoption.

The community reaction on Reddit was blunt but fair: the scary part here is how easy it is to trust something that looks official enough. That sounds obvious until you remember how most of us install tools: search, click, move on.

2. Reduce the blast radius on developer machines

The Nx postmortem is basically a reminder that your laptop is production-adjacent infrastructure.

If gh, cloud CLIs, npm auth, SSH keys, and 1Password sessions all live on the same always-on machine, a malicious extension does not need a kernel exploit. It just needs your normal workflow.

A few boring controls matter more than ever:

  • Prefer short-lived credentials over long-lived tokens.

  • Avoid leaving broad-scope GitHub tokens lying around in config files.

  • Re-check what gh auth and cloud CLIs can reach from a normal developer session.

  • Treat active secrets-manager sessions as privileged events, not a permanent desktop state.

If you installed Nx Console 18.95.0, Nx’s advice is the right one: assume the machine is compromised and rotate everything that machine could read or mint.

3. Verify that your package-manager hardening is actually real

This is the sneaky lesson from the Nx write-up.

Nx says the compromised repo had .npmrc configured with minimum-release-age=10080, which should have blocked a package published 77 minutes earlier. But the project’s pinned pnpm version predated that feature, so the config was silently ignored.

That is exactly the kind of security footgun developers hate: you think the control exists, everyone feels safe, and the guardrail is imaginary.

Don’t just set the policy. Prove it works.

pnpm --version
pnpm config get minimum-release-age
pnpm install

If your security policy depends on a package-manager feature, pin a version that supports it and test it in CI. “Configured” is not the same as “enforced.”

4. Require a second human for publish-capable workflows

One of Nx’s clearest fixes was also one of the most sensible: publishing Nx Console now requires approval through GitHub Actions environments with a reviewer who is not the person who triggered the workflow.

That should not be an edge-case fix for one repo. It should be standard for anything that can publish packages, release binaries, or ship editor extensions.

Pair that with the other change Nx called out:

  • Monitor GitHub audit logs for suspicious workflow-run deletions.

  • Pin GitHub Action SHAs instead of floating refs.

  • Make sure the hardening applies to all publish-capable repos, not just the important-looking ones.

That last part is where teams usually mess this up. The main package gets the full security treatment, but the sidecar repo, helper extension, or release utility stays soft. Attackers are very happy to take the side door.

My take

The most important thing about the Nx Console incident is not that a popular extension got hit. It is that the attack chain crossed package install, local workstation, editor marketplace, and GitHub org boundaries without needing anything especially exotic.

That means JavaScript teams need to stop separating “dependency security,” “developer tooling,” and “CI security” into different mental buckets. They are the same system now.

If I were running a JS platform team this weekend, I would do three things in order:

  • Audit installed editor extensions on machines with repo or publish access.

  • Rotate or narrow the credentials those machines can reach.

  • Review every publish-capable workflow for second-person approval and SHA pinning.

That is not glamorous work. It is also a lot more useful than pretending the problem ended because one bad extension version got unpublished.