npm Trusted Publishing flaw exposed 1,500+ npm packages to takeover

Vulnerabilidades Help Net Security hace 2 h

Publicada por 2 medios

También la publican CSO Online

Bloom Security researchers found that npm’s Trusted Publishing feature let an attacker push new versions of someone else’s package without stealing a credential. The attacker only needed to register a GitHub repository name the maintainer had left behind. Bloom counted more than 1,500 npm packages exposed this way, and GitHub, which owns npm, says it has shipped fixes.

The exposed packages have more than 10 million downloads in total and more than a million a month. That averages out to several hundred monthly downloads per package, but one hijacked package is enough. A malicious version can carry a postinstall script, code that npm runs automatically on every machine that installs the update.

Trusted Publishing, generally available since July 2025, replaces long-lived publishing tokens. A maintainer tells npm which GitHub repository and workflow file may publish a package. When that workflow runs, GitHub issues it a signed identity token, and npm exchanges it for a publish credential that expires within minutes.

npm recorded the repository by its name, the owner/repo string GitHub calls a slug. GitHub also assigns every repository and owner a permanent numeric ID that survives renames and transfers, and it puts both IDs in the token. npm did not check them. Once a maintainer renamed, transferred or deleted the bound repository, or the owner account was renamed or deleted, the old slug was free. Anyone could create a repository at that name, add a workflow file with the matching filename, and receive a publish credential for a package they did not own.

Bloom ran the attack end to end on a package and repositories its researchers controlled, publishing from a second organization’s repository that had claimed the freed slug. A release published this way also carries a valid provenance attestation, a signed build record, naming the attacker’s repository.

GitHub retires the names of repositories with more than 100 clones in the week before an owner account is renamed or deleted, which protects some packages. “We took this into account. Everything we considered vulnerable was pertaining to claimable slugs,” said Golan Myers , security researcher at Bloom Security.

Bloom reported the issue through GitHub’s bug bounty program on HackerOne on June 6, and GitHub validated it on June 9. Bloom says the last reply it got was on July 8, and that six follow-ups after that, including a mediation request to HackerOne, went unanswered.

A GitHub spokesperson told Help Net Security: “We learned of this event through our bug bounty program and worked to validate the report and ship fixes to remediate the issue. Unvalidated Trusted Publishing configurations now expire 48 hours after creation and can no longer authorize publishing. This limits the risk of trusting a repository or project name that changes ownership.”

GitHub announced the change on October 2, and npm’s documentation says a configuration’s first successful publish binds it to the repository’s “immutable identity.” GitHub’s statement does not say whether configurations that published before the change were bound retroactively. Myers said it is unknown whether anyone exploited the flaw in the wild.

Bloom argues that AI coding agents make flaws like this reach further. Based on telemetry from dozens of organizations, it estimates that agents on a typical endpoint install about 70 packages a month, and close to 350 on developer machines, not counting dependencies. Those installs usually happen without a review of the package or its maintainer.

“ AI agents are changing the game – developers are no longer the only ‘developer software’ consumers. As such, issues as this are impactful for all users, as opposed to the historical conception,” Myers said.

If you maintain a package with Trusted Publishing, run npm trust list and confirm each listed repository still resolves to one you control. Delete and re-create any binding that points at a renamed or transferred repository, and remove the binding before deleting a repository.

Bloom is not publishing the affected package names, so users of npm packages cannot check against a list. They can verify that a package’s provenance attestation names the repository the project is supposed to come from.

Bloom says npm’s GitLab trusted publishing integration has the same weakness.