Bloom Finds 1,500+ npm Packages Exposed by Trusted Publishing Flaw

Bloom Security says an npm Trusted Publishing flaw exposed more than 1,500 packages. New configurations now expire unless validated within 48 hours; maintainers should still audit bindings and releases.

Reader ratingRate this article

Loading reader rating…

Privacy-conscious voting uses a signed random browser identifier and a short-lived network hash; the rating tables contain no raw IP-address column.

Reader ratings require JavaScript; the article remains fully readable without it.

Software supply-chain security

Researchers disclosed “SlugFest,” a flaw in unvalidated npm Trusted Publishing configurations that could let a newly claimed GitHub repository name inherit publishing trust before the legitimate configuration completed its first successful publish. GitHub has implemented a 48-hour expiration safeguard, but package maintainers should still audit their trust bindings and release history.[1][2]

Reporting cutoff: 2026-10-13T20:26:38Z

Fix implemented[2]Controlled reproduction[1]In-the-wild exploitation unknown[4]
Affected condition

An unvalidated Trusted Publisher binding, a GitHub slug that becomes claimable, and no prior successful publish that bound the immutable repository identity.[1]

Researcher estimate

1,500+ packages
More than 10 million cumulative downloads and more than one million monthly downloads.[1][4]

Current safeguard

New configurations must complete their first successful publish within 48 hours; otherwise they expire and cannot authorize publishing.[2][3]

This is an audit event—not evidence that 10 million users were compromised. Bloom’s figures describe the historical download footprint of packages it classified as exposed. Bloom did not publish the package list, and Help Net Security reports that exploitation in the wild remains unknown.[1][4]

What went wrong

npm Trusted Publishing uses OpenID Connect so supported CI/CD workflows can request short-lived publishing credentials instead of storing long-lived write tokens. npm’s documentation says this reduces the risks of credentials being leaked, logged or left unrotated.[3]

Bloom Security says the vulnerable state existed before an initial successful publish validated the configuration. During that state, npm matched a human-readable GitHub owner/repository path—the repository “slug”—and workflow filename. If the original owner or repository was renamed, transferred or deleted and the old path became claimable, a different repository could occupy that name while having a different immutable repository ID.[1]

Bloom reports that it reproduced the issue end to end using an npm scope and GitHub repositories controlled by its researchers. After reclaiming the freed slug from a second organization, the researchers published to their own test package without stealing the legitimate maintainer’s npm or GitHub credentials.[1]

The preconditions were narrow. This report does not establish that every npm package, every Trusted Publishing configuration or every package with one of the counted downloads was compromised. The condition required an unvalidated binding, no first successful publish, and a claimable former slug.[1]

What GitHub and npm changed

GitHub announced on October 2 that unvalidated npm Trusted Publishing configurations now expire 48 hours after creation and can no longer authorize publishing. A first successful publish validates the configuration and exempts it from expiration; changing the repository or project identity requires a new trust relationship and a fresh 48-hour window.[2]

npm’s current documentation matches that behavior: a new configuration must complete its first successful publish within two days, which validates the configuration and binds it to the repository’s immutable identity. An expired configuration must be deleted and recreated before use.[3]

The same GitHub notice says npm now rejects trusted-publishing tokens from GitHub Actions issue_comment events, in addition to the existing pull_request_target restriction. Affected projects should move publishing to an allowed event such as push, release or workflow_dispatch.[2]

Why provenance still needs interpretation

npm says Trusted Publishing automatically generates provenance attestations for eligible public packages published from GitHub Actions or GitLab CI/CD. Provenance can show where and how a package was built, but Bloom’s controlled reproduction showed why consumers should verify that the attested source repository is the one the project is expected to use—not merely that an attestation exists.[1][3]

Maintainer checklist

  1. Inventory the bindings. Review every npm package your organization maintains and its configured Trusted Publishers. npm permits multiple independent publisher connections per package, so inspect each one.[3]
  2. Confirm repository ownership. Bloom recommends using npm trust list for each package and checking that every listed repository slug still resolves to a repository your organization controls.[1]
  3. Replace stale connections. npm says existing connections cannot be edited. Delete and recreate a connection when its repository identity or required fields must change; Bloom specifically recommends doing this after a rename or transfer.[1][3]
  4. Complete validation promptly. Perform the intended first publish inside the two-day window and verify that the resulting release and provenance name the expected repository.[2][3]
  5. Review publication history. Bloom advises looking for releases that were not initiated from the expected repository or workflow. Treat an unexplained release as an incident requiring evidence preservation, containment and investigation—not as a routine version cleanup.[1]
  6. Reduce token exposure. After Trusted Publishing works, npm recommends restricting traditional publishing tokens, revoking obsolete automation tokens and considering staged publishing with maintainer approval.[3]

Guidance for development teams consuming npm packages

Bloom did not publish the affected-package names, so there is no reliable public list against which teams can mass-remove dependencies. Help Net Security recommends checking whether a package’s provenance attestation identifies the repository the project is expected to use.[4]

General practical guidance: keep lockfiles and dependency allowlists under normal change control, stage updates, review unexpected maintainer or repository changes, and investigate unusual new versions before promoting them. Do not mass-uninstall packages based solely on aggregate exposure figures; those figures do not identify which packages were involved or prove malicious publication.

What remains unknown

  • Whether malicious actors exploited SlugFest in the wild remains unknown.[4]
  • Bloom did not publish the names of the more than 1,500 packages, preventing independent package-by-package verification.[1][4]
  • The current number of configurations that still require maintainer cleanup was not established by the reviewed sources.
  • Bloom says the GitLab Trusted Publishing integration had the same weakness, but this article did not find a separate GitLab controlling-source statement at the reporting cutoff.[1]

Bottom line

The 48-hour expiration rule closes the open-ended unvalidated state described by the research, and a first successful publish binds the configuration to an immutable repository identity. Maintainers should still audit every existing binding, replace stale repository references, complete validation promptly, verify provenance source identities and investigate unexpected releases. Consumers should not interpret Bloom’s aggregate download figures as evidence that their systems were compromised.[1][2][3]

Sources

  1. Bloom Security: SlugFest research
  2. GitHub Changelog: Unvalidated npm trusted publishing configurations now expire
  3. npm documentation: Trusted publishing for npm packages
  4. Help Net Security: npm Trusted Publishing flaw exposed 1,500+ npm packages to takeover

Source note: The package and download estimates are Bloom Security’s figures. Help Net Security reported those figures but did not independently enumerate the unpublished package list. Current mitigation behavior was checked against GitHub’s announcement and npm’s documentation.