What is a maintainer account takeover?
The right package name, published by the wrong person.
A maintainer account takeover is an attacker gaining the right to publish a real package and releasing a malicious version under the package's own name, so npm install axios or pip install litellm fetches the attacker's code. In 2026 publish rights came from compromised maintainer machines, stolen tokens, an expired email domain and hijacked release pipelines. The sections below cover each route, why provenance did not stop the hijacked releases, and the release hold and publisher signals that buy time.
Questions and answers
What is a maintainer account takeover?
A maintainer account takeover is an attacker gaining the right to publish a real package, then releasing a malicious version under the package’s own name. No lookalike name is needed: the version comes from the account, token or CI pipeline that publishes the genuine releases, so npm install axios or pip install litellm fetches the attacker’s code. Most of the 2026 attacks in Chain305’s teardowns took this route. In practice, the malicious axios 1.14.1 came from the lead maintainer’s own npm account in March 2026, litellm 1.82.7 and 1.82.8 from a PyPI token taken from CI, and the TanStack versions of Mini Shai-Hulud from TanStack’s own trusted-publishing setup. The payload usually runs at install or import, and the registry usually removes the versions within hours. That short window is why a release hold and publisher-change signals matter more here than a vulnerability database.
How do attackers get publish rights?
Attackers got publish rights in 2026 in four ways, according to the incident reports behind Chain305’s teardowns:
- A compromised maintainer machine. Social engineering put remote-access malware on the axios lead maintainer’s PC, and two-factor authentication did not help.
- A stolen long-lived token. litellm’s PyPI token was taken from CI through a tampered Trivy, durabletask’s PyPI token, kept in GitHub secrets, was most likely dumped from the repository (Wiz), a developer’s GitHub OAuth token published pgserve, and onering’s crates.io token was stolen with the maintainer’s GitHub account.
- An expired email domain. node-ipc’s dormant co-maintainer used an address on a lapsed domain, which someone re-registered, most likely to reset the npm password.
- A hijacked release pipeline. TanStack, Bitwarden, SAP CAP and the Red Hat packages hit by Miasma were published through their own CI.
A PyPI API token does not need the account’s second factor, so litellm’s two-factor authentication did not stop the upload.
How is trusted publishing abused?
Trusted publishing is abused by making the project’s own CI workflow request the short-lived publish token, so the malicious release looks like any other. npm and PyPI trusted publishing exchange an OpenID Connect token from CI for a publish token, which removes long-lived secrets but trusts the code that runs in the authorised workflow. In May 2026 a pull_request_target workflow ran fork code that poisoned the GitHub Actions cache, and TanStack’s release workflow restored the cache, so attacker code read the token from runner memory. In April a compromised Bitwarden engineer’s GitHub account pushed a branch whose rewritten workflow published @bitwarden/cli 2026.4.0. SAP CAP’s npm trusted-publisher setting trusted any branch that ran the release workflow. The fixes in those reports are a required approval on the release environment, trust scoped to one workflow, and npm’s advice to disallow token publishing once trusted publishing is set up.
Does provenance stop a hijacked release?
No. Provenance proves where a package was built, and a hijacked pipeline builds in the right place. npm’s documentation says a provenance attestation links a package to its source repository and build instructions, and that provenance “does not guarantee the package has no malicious code”. The 96 malicious @redhat-cloud-services versions of the Miasma worm in June 2026 carried valid npm provenance pointing at the real Red Hat repositories, because the worm published through each victim’s own trusted-publishing setup. In practice, provenance helps in the opposite case: a release that skips the pipeline. axios 1.14.0 was published by the project’s GitHub Actions workflow with trusted publishing, while the malicious 1.14.1 came straight from the maintainer’s account, outside the pipeline. A consumer can check attestations with npm audit signatures, and a version that drops the provenance its predecessors carried deserves a hold and a closer look before anyone installs it.
Which signals give a hijacked release away?
The signals that give a hijacked release away are changes in who published it, how and what it contains. Five of them separated the hijacked releases in Chain305’s 2026 teardowns from ordinary ones:
- A publisher change. node-ipc’s malicious versions came from a co-maintainer who had never published node-ipc, in the package’s first release in 21 months.
- A release that skips the usual pipeline. axios 1.14.1 came from the maintainer account, while 1.14.0 came from GitHub Actions.
- No matching git tag. None of
pgserve1.1.11 to 1.1.14 ordurabletask1.4.1 to 1.4.3 had one. - A new dependency or install script. axios 1.14.1 added only
plain-crypto-js, first published 18 hours earlier, and@bitwarden/cli2026.4.0 carried the first install script in the package’s history. - A change in shape. The TanStack versions were 3.7 times larger than the previous release and added a git dependency.
Each signal also fires on legitimate handoffs and refactors, so the signals justify a hold and a review rather than a hard refusal.
How does a release hold help?
A release hold is a delay before a new version can be installed, so a hijacked release is usually reported and removed before anyone gets it. The 2026 windows were short. PyPI quarantined litellm 1.82.7 and 1.82.8 after about 40 minutes, npm removed the malicious axios versions about three hours after the first publish, @bitwarden/cli 2026.4.0 was served for about an hour and a half, and npm removed the last malicious TanStack version 4 hours 35 minutes after publish. Package managers offer the hold themselves: min-release-age for npm, --uploaded-prior-to for pip, exclude-newer for uv and solver.min-release-age for Poetry. A hold only delays: once the cutoff passes, the version installs unless a malware feed has listed it. A hold also misses a rewrite of an existing version, such as the May 2026 Laravel-Lang attack, which re-pointed old Composer tags at new commits.
Where does a package firewall fit?
A package firewall is where the hold and the publisher checks apply once for the whole organisation, on the registry URL every client uses. Chainsaw holds every new version for 48 hours by default, extended to 96 hours when a release changes shape, and refuses packages first published less than 1 day ago. Its publisher-change signal compares the publishers of a new version with the previous one on npm, PyPI, RubyGems, NuGet, Maven and Gradle. The rule built on the signal starts in monitor mode, because a normal maintainer handoff looks the same. Policy can also require npm provenance or Sigstore signatures. When we measured Chainsaw against 58 attacks from 2026, the hold and the malware feed kept out the hijacked axios, node-ipc and TanStack versions, and the age rule refused axios’s injected dependency on day 0. The takeover itself happens at the registry or the email provider, where a firewall has no view. The 2026 attack results.
Sources
Each fact on this page links its source, and the list below is the full set: npm and PyPI documentation, GitHub and OSV advisories, the CISA alert on axios, the LiteLLM and TanStack incident reports, and Chain305’s teardowns of the 2026 attacks named above.
- npm Docs, trusted publishing for npm packages, generating provenance statements and config:
min-release-age. - PyPI docs, Trusted Publishers.
- CISA, Supply Chain Compromise Impacts Axios Node Package Manager, 20 April 2026.
- GitHub Advisory Database, GHSA-g7cv-rxg3-hmpx / CVE-2026-45321 (TanStack) and GHSA-g98r-qjhg-4fmr (@bitwarden/cli).
- SAP, GHSA-pvw4-cvr4-97p8 / CVE-2026-46421 (@cap-js).
- OSV, MAL-2026-4174 (durabletask).
- LiteLLM, Security Update: Suspected Supply Chain Incident, March 2026.
- TanStack, Postmortem: TanStack npm supply-chain compromise, May 2026.
- Chain305 teardowns: axios, Mini Shai-Hulud and TanStack, Bitwarden CLI, SAP CAP, Miasma, litellm, durabletask, pgserve, node-ipc, onering and Laravel-Lang.
Most hijacked releases last hours
Hold new versions until the feeds catch up
Chainsaw's release hold is a 48-hour delay on every new package version by default, or 96 hours when a release changes shape. Hijacked releases in 2026 were usually reported and removed within hours, so the hold outlasts most of them. In Chain305's tests against 58 attacks from 2026, the hold and the malware feed kept out the hijacked axios, node-ipc and TanStack versions, and the age rule refused axios's injected dependency on day 0. Start a free org in monitor mode to see which new releases and publisher changes Chainsaw would hold or refuse.