Tutorials

npm Killed Classic Tokens — 2026's Worms Didn't Care

· Tutorials

npm supply chain security in 2026: classic tokens are gone, trusted publishing is live, and two worm outbreaks still got through anyway.

npm Killed Classic Tokens — 2026's Worms Didn't Care

Last updated: September 9, 2026 · 6-minute read

796 npm packages got backdoored in a single day last November, and every one of them was published through npm's legitimate registry with the credentials of a legitimate maintainer. That was the second worm in three months. The third and fourth waves landed in 2026 — after npm shipped the biggest trust overhaul in the registry's history. The uncomfortable lesson in the timeline: the controls worked exactly as designed, and that was not enough.

The worm that rewrote the rules

Security researchers at Datadog documented the Shai-Hulud worm in September 2025: a self-replicating npm package that stole maintainer credentials and used them to backdoor hundreds of legitimate packages. CISA issued an advisory. The ecosystem patched, revoked, and moved on.

It moved on too soon. On November 24, 2025, a second worm — Shai-Hulud 2.0 — ran the same playbook with uglier features. Datadog's analysis puts it at 796 unique compromised packages totaling over 20 million weekly downloads. The payload was a credential stealer that exfiltrated secrets through public GitHub repositories. The worm spread without a command-and-control server by reading its own payload and re-publishing it into every package its stolen tokens could reach. As a last resort, it could destroy the victim's home directory. Datadog estimates data from more than 500 GitHub users across 150-plus organizations was exfiltrated — a lower bound, from public evidence only.

The details matter less than the shape: the attack surface was not code. It was trust.

What npm actually changed

npm and GitHub published their "plan for a more secure npm supply chain" in September 2025. The rollout that followed rewired how packages get published:

That is a genuinely aggressive cleanup. Classic tokens — the forever-valid, copy-paste-anywhere credentials that made Shai-Hulud possible — are gone for good. Trusted publishing lets GitHub Actions mint a short-lived OIDC token per release, so there is nothing to steal in the first place. Packages published this way carry SLSA provenance signed into Sigstore's public transparency log. Analysts rate that combination at roughly SLSA Build Level 2 — the build is provably tied to a specific workflow, repository, and ref.

A year ago, publishing malware to npm required stealing a token that never expired. Now it requires compromising the pipeline itself. So attackers compromised the pipeline itself.

TanStack: when the pipeline is the attack

On May 11, 2026, 84 malicious versions went out across 42 @tanstack/ packages — the "Mini Shai-Hulud" wave, per Snyk. TanStack's own postmortem is the best documentation of it: the attacker chained a pullrequesttarget Pwn Request with GitHub Actions cache poisoning across the fork-base trust boundary. No token was stolen. The CI workflow was tricked into doing the publishing on the attacker's behalf.

Endor Labs counted it as the fifth Shai-Hulud wave in eight months. The technique drifted from stealing credentials to abusing the automation that credentials used to flow through — which is precisely the surface npm's overhaul was busy shrinking.

Red Hat: when every control passes

The June 1, 2026 incident is the one that should reframe how you think about provenance. More than 30 packages under the @redhat-cloud-services namespace went out carrying a credential-stealing worm named "Miasma". Boost Security's research team traced the mechanics: a compromised maintainer account pushed a counterfeit release workflow to short-lived throwaway branches, which minted npm OIDC tokens and published the malicious versions.

Here is the part Boost Security put better than anywhere else: every trust control in the path passed. The packages carried valid SLSA provenance. npm trusted publishing accepted them. Branch protection on the main branch was never touched — because nothing pushed to it. Trusted publishing anchors trust to a workflow file existing on any branch, not to a protected release identity. The transparency log permanently recorded that the build came from a throwaway branch. Nothing anywhere checked that.

This is not an argument that trusted publishing failed. It is an argument that provenance proves where a package was built — not whether the build was supposed to happen.

The maintainer checklist that actually helps

Derived from the incident reports above, not from a personal audit — the pattern across 2026's outbreaks is consistent enough to act on:

1. Turn on trusted publishing for every npm package you maintain from GitHub Actions. Killing long-lived tokens removes the entire Shai-Hulud class of credential theft. 2. Gate the publish workflow with a GitHub Environment, and restrict it to your release branch. Environments give you the protected-identity layer that trusted publishing alone lacks — the exact gap Miasma walked through. 3. Pin third-party Actions to full-length commit SHAs, especially in the release path. Cache poisoning and Pwn Requests ride in through dependencies of your workflow. 4. Treat pullrequesttarget as hostile by default. TanStack's postmortem is a complete case study of why; if a workflow checks out untrusted code with privileged secrets, redesign it. 5. Read the provenance after releases. The ref, the workflow path, and the commit are all in the transparency log. A release minted from an unexpected branch is an incident in progress.

The installer side

Consumers of packages have a shorter list, and it is mostly about blast radius. A committed lockfile turns "latest everything" into a reviewed diff — a malicious version bump shows up in code review instead of silently landing in CI. npm ci instead of npm install in CI keeps installs reproducible. Pulling new versions only through dependabot-style PRs means every upgrade passes the same eyes as source changes.

The honest caveat: none of this scales to a 2,000-dependency tree audited by one tired human. The registry-level fixes — revocation, OIDC, provenance — are doing the heavy lifting; the checklist above just shrinks your personal attack surface while the ecosystem finishes the job. This site's own repo runs on npm, and its lockfile is the whole strategy in miniature: boring, reviewed, and boring on purpose.

TL;DR

  • Shai-Hulud 2.0 backdoored 796 npm packages with 20-plus million weekly downloads in one day — the attack surface was maintainer trust, not code.
  • npm revoked all classic tokens on December 9, 2025, capped granular tokens at 90 days, and made OIDC trusted publishing the recommended path.
  • TanStack's May 2026 compromise chained pullrequesttarget abuse with Actions cache poisoning — the pipeline itself was the attack.
  • The Red Hat "Miasma" incident passed every control: valid provenance, trusted publishing, untouched branch protection — because trusted publishing anchors to a workflow file, not a protected release identity.
  • Environment-gate your publish workflow, pin Actions to SHAs, and review provenance refs — those close the exact gaps 2026's worms used.

Keep reading

  • 78 red CI builds, 3 root causes, one commit
  • Free AI code review with GitHub Actions
  • Automation & CI/CD — the solo-dev workflow hub

---

Not affiliated with npm, GitHub, Red Hat, or TanStack. Sources: Datadog Security Labs, TanStack's postmortem, Boost Security Labs, GitHub's npm security announcements, Snyk, Endor Labs.

ansaribilal.com — technology, tested in public.