npm trusted publishing fix closes SlugFest repo-slug hijack

npm trusted publishing, the OIDC-based replacement for long-lived publish tokens, matched GitHub repositories by their owner/repo name rather than an immutable ID. Bloom Security found that an attacker who claimed a freed repository name could inherit the right to publish someone else's package. GitHub has shipped a partial fix. Maintainers still need to audit their bindings.

What happened

Bloom Security researcher Golan Myers published the "SlugFest" write-up on October 13, 2026. With trusted publishing, a maintainer registers a GitHub repository with npm. At publish time, a GitHub Actions workflow requests a short-lived OIDC token, and the registry exchanges it for a publish credential. According to Bloom, npm stored only the human-readable slug (owner/repo) and did not record GitHub's numeric repository_id and repository_owner_id until the first successful publish.

That left a gap. If a maintainer renamed, transferred or deleted a repository before a trusted publish completed, the old slug became free to claim. An attacker could create a repository at that name, add a workflow file with the bound filename, mint an OIDC token, and receive a valid publish credential for a package they did not own. No stolen credentials were needed. Bloom counted more than 1,500 packages with trusted publishing configured that were exposed this way, with more than 10 million total downloads and over 1 million a month. Bloom did not name affected packages, saying the issue is still prevalent.

Bloom reported the flaw through GitHub's HackerOne program on June 6, 2026, and it was validated on June 9. GitHub announced the fix in an October 2 changelog post that does not mention the research:

  • Unvalidated trusted publishing configurations now expire 48 hours after creation and can no longer authorize publishing.
  • A configuration is validated by its first successful publish and is then exempt from expiry.
  • Changing the repository or project identity requires a new trust relationship with a fresh 48-hour window.
  • npm now rejects trusted publishing tokens from GitHub Actions issue_comment events, in addition to the existing pull_request_target restriction.

No CVE has been assigned.

Why it matters

This is a federation trust-policy mistake. Any OIDC trust between a CI platform and a cloud account, registry or vault should be keyed on identifiers that cannot be reissued. Names can be renamed, transferred and reclaimed. Myers described it this way:

It is like a lock that checks the address on the door rather than who owns the house.

Bloom also points out that the fix is a time limit, not an ID check. The approach Bloom recommends, which it says PyPI already uses, is to record the numeric IDs when the binding is created and check them at token exchange. The same question applies to your own cloud OIDC trust policies: do they match on a repository name or on something immutable?

This follows our GhostAction coverage. Both incidents target the CI identity that publishes software, not a human login.

What to check in your environment

  • Inventory your trusted publisher bindings. Review the trusted publisher settings for each package you maintain. Bloom's write-up suggests a npm trust list command for this; it does not appear in the npm trusted publishers documentation we cite, so verify it against your npm CLI before relying on it. Confirm that every bound slug still points to a repository your organization controls.
  • Recreate bindings for renamed or transferred repositories. Delete the existing binding, create a new one, and publish within 48 hours so it validates.
  • Delete bindings before renaming, transferring or deleting a repository. Make this a step in your repo-decommissioning and org-migration runbooks.
  • Look for expired configurations. They stay visible in trusted publisher settings and have to be recreated, not edited.
  • Move publish workflows off issue_comment to a permitted event such as push, release or workflow_dispatch, as GitHub's changelog advises.
  • Watch for unexpected publishes. Compare new versions of your packages against your own release records.
  • Review OIDC trust conditions elsewhere (our analysis, not from the sources). The same naming weakness may exist beyond npm. Check whether cloud or vault trust policies for GitHub Actions match on mutable repository names.

References

Original source: Bloom Security