The Name Is Not the Repository: SlugFest Turns Abandoned GitHub Slugs Into npm Publish Rights

Trusted Publishing was supposed to end the era of stolen npm tokens. Generally available since July 2025, it replaces long-lived publishing credentials: a maintainer declares which GitHub repository and workflow file may publish a package, GitHub issues that workflow a signed identity token at run time, and npm exchanges it for a publish credential that expires within minutes. No token to phish, no secret to leak. Research from Bloom Security disclosed on 13 October 2026 — dubbed SlugFest — shows the binding was made to the one identifier the attacker can re-register. npm recorded the repository by its slug, the human-readable owner/repo string. 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. So once a maintainer renamed, transferred or deleted the bound repository — or the owner account itself was renamed or deleted — the old slug was free, and anyone who claimed it and added a workflow file with the matching filename received a publish credential for a package they did not own. Bloom counted more than 1,500 exposed packages totalling over 10 million downloads, with no credential theft required at any step.

The wording that matters most in the reporting is the understated one: this was a package-takeover path, not an active malware campaign. Bloom proved it end to end on packages and repositories its own researchers controlled — publishing from a second organisation’s repository that had claimed the freed slug — and confirmed the grimmest detail: a release published this way also carries a valid provenance attestation, the signed build record, naming the attacker’s repository. The one signal the ecosystem built to distinguish legitimate builds from impostors would have vouched for the impostor. There is a partial mitigation worth knowing accurately: 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. Bloom’s Golan Myers is quoted as saying the researchers accounted for that — everything they counted as vulnerable used a genuinely claimable slug.

Four months from report to fix, via silence

The disclosure timeline is doing half the argumentative work here, and every date below is as reported. Bloom filed through GitHub’s HackerOne bug bounty programme on 6 June 2026; GitHub validated the report on 9 June. Bloom says the last reply it received came on 8 July, and that six follow-ups after that — including a mediation request to HackerOne — went unanswered. GitHub announced the change on 2 October: unvalidated Trusted Publishing configurations now expire 48 hours after creation and can no longer authorise publishing, and npm’s documentation says a configuration’s first successful publish binds it to the repository’s immutable identity. A GitHub spokesperson is quoted confirming the fix and framing it as limiting “the risk of trusting a repository or project name that changes ownership.”

Two gaps remain open, and both are stated carefully rather than filled in. GitHub’s statement does not say whether configurations that published before the change were bound retroactively to the immutable identity — which decides whether the 48-hour expiry closes the hole for every existing binding or only for new ones. And Myers says it is unknown whether anyone exploited the flaw in the wild; Bloom is not publishing the affected package names. A 118-day window between validation and fix, with no public list and no retroactivity statement, is the part of this story incident responders will be living with for a while.

Why this site treats it as an agent-security story

Bloom’s argument, and the reason this belongs on an agent-security front page rather than only a supply-chain one: AI coding agents have become high-volume, low-scrutiny package consumers. Citing telemetry from dozens of organisations, Bloom estimates agents on a typical endpoint install roughly 70 packages a month, nearly 350 on developer machines, dependencies not counted — usually without any review of the package or its maintainer. A hijacked release with a postinstall script (code npm runs automatically on install) and a valid provenance attestation is precisely the payload that sails through an agent-driven install pipeline: no human reads the diff, the signature checks out, the name is the name everyone trusts. Myers’ quoted line lands because it is structural, not rhetorical: developers are no longer the only consumers of developer software. Every consumer that cannot judge trust has to inherit it from infrastructure — and SlugFest shows the infrastructure was judging by display name.

What to do

  • If you maintain a package with Trusted Publishing, audit the binding now. 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 — a deleted repo’s slug is exactly what this attack claims.
  • If you consume npm packages, verify provenance against expectation, not just validity. Bloom is not publishing the affected names, so there is no list to check against. Confirm a package’s provenance attestation names the repository the project is supposed to come from; a valid signature from an unfamiliar repository is the signature SlugFest forges by design.
  • If agents install packages in your environment, pin and gate. Lockfiles, private registries or caching proxies, and install-time sandboxing turn a silent takeover into a visible diff. Seventy unattended installs a month per endpoint is seventy rolls of someone else’s hygiene — the Tensorlake Shai-Hulud compromise already showed what valid-looking provenance costs when nobody inspects it, and the Shai-Hulud retrospective is the playbook for how agents become distribution.
  • Treat mutable names as display strings everywhere. The general lesson is one this site has now written at three layers in a fortnight: a trust parameter that defaults to the convenient value eventually gets omitted, a validator that checks syntax eventually meets semantics it never considered, and — here — an identity check that compares the label eventually meets a label someone else registered. Bind to the immutable ID at configuration time and verify it at use time; Bloom’s own recommendation is exactly that: store the repository and owner identifiers when the publisher is configured, then verify the repository identifier in the OIDC token at credential exchange.

Verification note. The Help Net Security report (Mirko Zorz, 13 October 2026) was read first-hand in full; the mechanism description, the 1,500-plus package and 10-million-download counts, the June 6 / June 9 / July 8 / October 2 timeline, the six unanswered follow-ups including the HackerOne mediation request, the 100-clone name-retirement detail, the Myers and GitHub-spokesperson quotes, the end-to-end researcher-controlled proof, the 48-hour-expiry and immutable-identity fix description, the two open gaps (retroactivity unstated, wild exploitation unknown), the agent-install telemetry figures and the remediation advice are that article’s reporting, relayed as reported. The “SlugFest” name and Bloom Security attribution are corroborated across CSO Online, GBHackers and The Next Web coverage found via search. We did not claim any freed slug, publish any package, or test any binding; the exploitability claims are Bloom’s, verified by them on infrastructure they controlled. Cross-references to our Shai-Hulud coverage and the composition-failure reading are our editorial analysis. There is no CVE identifier for this flaw and we invent none.

Sources: