SlugFest: npm trusted publishing trusted repository names, so reclaimed names could publish
Bloom Security found npm trusted publishing matched GitHub repositories by owner/name until first publish, letting anyone who reclaimed a renamed or deleted slug mint publish tokens for more than 1,500 packages. npm now expires unvalidated configurations after 48 hours.
Bloom Security disclosed SlugFest on October 13: npm trusted publishing identified the GitHub repository allowed to publish a package by its owner/repository name, and only stored the permanent numeric repository ID after the first successful publish. If a maintainer configured trusted publishing and then renamed, transferred or deleted the repository, or the owner account, before publishing from it, anyone could register the freed name, add a workflow with the expected filename, and exchange a GitHub Actions OIDC token for a valid npm publish credential with no maintainer secrets. Bloom counts more than 1,500 exposed packages with over 10 million total downloads and reports no confirmed exploitation. It reported the issue on June 6. GitHub's October 2 changelog makes unvalidated configurations expire 48 hours after creation and also rejects trusted publishing tokens from issue_comment workflow events.
Why it matters
Trusted publishing replaces long-lived npm tokens with short-lived OIDC exchanges, which is the right direction, but the trust is only as good as the identifier it binds to. A name that can be released and reclaimed is not an identity. This is the same lesson as orphaned accounts: the binding outlived the thing it pointed at.
Maintainers should run npm trust list, confirm every bound repository still exists under their control, delete and recreate bindings after any rename or transfer, remove bindings before deleting a repository, and publish once immediately after creating a new binding so it locks to the numeric ID. Watch for publishes you did not start. The same check applies to workload identity federation trust policies in cloud accounts that match on repository name. Bloom's write-up is here and GitHub's change is in the changelog.
Source: The Hacker News
Related on Start with Identity
- BlogShai-Hulud reaches the Tensorlake npm SDK, with a wiper that fires when you revoke the stolen token
tensorlake@0.5.144, published from the project's own release workflow after commits pushed under a maintainer's name, carried a ChainDrop/Shai-Hulud credential
- BlogA hijacked AI coding assistant session spread Shai-Hulud to about 100 internal repositories
Mandiant describes an intrusion at an unnamed SaaS provider where a poisoned package, recommended through a developer's AI coding assistant session, led to stol
- BlogCrowdSec kept a departing engineer's GitHub access open, and lost 170 private repositories through it
An engineer's laptop was infected in the May TanStack npm attack. Eleven days later his still-active GitHub OAuth token was used to copy about 170 of CrowdSec's
- GlossaryAuthorization Code Flow
The recommended OAuth 2.0 flow for apps with a user: the app receives a short-lived code, then exchanges it for tokens from a back channel. Combined with PKCE f
- GlossaryCIBA
Client-Initiated Backchannel Authentication. An OpenID Connect flow where authentication is initiated on one device and approved on another, useful for call cen
- GlossaryClaims
Statements about a subject carried in a token, such as subject identifier, email, roles, or expiry. Relying parties make authorization decisions from claims, so