Full Report
GitHub has taken the step of expiring unvalidated npm trusted publishing configurations 48 hours after creation after researchers found that it was possible for an attacker to push new versions of a different user's package without having to steal their credentials. "Your configuration becomes validated and exempt from expiry after its first successful publish," the Microsoft-owned subsidiary
Analysis Summary
# Vulnerability: npm Trusted Publishing Configuration Hijacking (Slug Squatting)
## CVE Details
- **CVE ID:** Not explicitly assigned in the report (Referenced as a "loophole" or architectural flaw by GitHub).
- **CVSS Score:** N/A (High Severity Impact)
- **CWE:** CWE-287: Improper Authentication / CWE-668: Exposure of Resource to Wrong Sphere
## Affected Systems
- **Products:** npm (Node Package Manager) Registry integration with GitHub Actions.
- **Versions:** All npm packages using Trusted Publishing via OIDC prior to October 2026.
- **Configurations:** Packages where a Trusted Publisher was configured for a GitHub repository, but a successful publish had **not yet occurred**, or where the repository slug (owner/repo) was abandoned, renamed, or transferred.
## Vulnerability Description
The flaw stems from how npm validated GitHub repositories during the initial "Trusted Publishing" setup. Instead of using GitHub’s unique, immutable numeric repository ID, npm initially relied on the **repository slug** (the "owner/name" string).
If a maintainer configured a trusted publisher but hadn't published a version yet, the "lock" was tied to the address (the URL slug) rather than the specific repository instance. An attacker could "squat" on a slug that became available (via renaming or deletion), create a new repository under that same name, and inherit the trust relationship. This allowed the attacker to push malicious package versions to npm as a legitimate maintainer without stealing credentials.
## Exploitation
- **Status:** PoC available (Discovered and demonstrated by Bloom Security).
- **Complexity:** Medium
- **Attack Vector:** Network
- **Pre-requisites:** The victim must have an unvalidated/pending trusted publisher configuration, and the attacker must be able to claim the specific GitHub slug associated with that configuration.
## Impact
- **Confidentiality:** Low (Focus is on code injection rather than data theft).
- **Integrity:** **High** (Attackers can push malicious code updates to legitimate packages).
- **Availability:** Medium (Potential for service disruption via malicious updates).
## Remediation
### Patches
- **GitHub/npm Platform Update:** GitHub has implemented a **48-hour expiration** for unvalidated npm trusted publishing configurations.
- **Validation Binding:** Configurations now become exempt from expiry and bind to the GitHub **immutable ID** only after the first successful publish.
### Workarounds
- **Immediate Publishing:** Developers should complete a successful publish immediately after configuring a Trusted Publisher to bind the identity.
- **Slug Monitoring:** Avoid renaming or deleting repositories that are currently linked to active npm publishing configurations.
## Detection
- **Indicators of Compromise:**
- Unexpected package versions published to npm that do not correlate with internal development history.
- New repositories created at old, renamed, or deleted "owner/repo" paths.
- **Detection Methods:**
- Review npm account "Trusted Publishers" settings for any unrecognized repositories.
- Audit GitHub Action logs for unauthorized `publish` events.
## References
- **Vendor Advisory:** [https://github.blog/changelog/2026-10-02-unvalidated-npm-trusted-publishing-configurations-now-expire/](https://github.blog/changelog/2026-10-02-unvalidated-npm-trusted-publishing-configurations-now-expire/)
- **Researcher Blog:** [https://bloom.security/blog/slugfest-millions-of-ai-agents-download-exposed-npm-packages](https://bloom.security/blog/slugfest-millions-of-ai-agents-download-exposed-npm-packages)
- **npm Documentation:** [https://docs.npmjs.com/trusted-publishers#trusted-publisher-configuration-expiry](https://docs.npmjs.com/trusted-publishers#trusted-publisher-configuration-expiry)