Skip to main content
npm Maintainer Accounts Hijacked: What Staged Publishing FixesIncident
4 min readFor Security Engineers

npm Maintainer Accounts Hijacked: What Staged Publishing Fixes

What Happened

Between 2021 and 2024, attackers compromised multiple npm maintainer accounts to inject malicious code into legitimate packages. They gained access through credential stuffing, phishing, and session token theft. Once inside, they published malicious versions of popular packages that were downloaded thousands of times before detection.

The attack pattern was consistent: compromise a maintainer account, publish a malicious version that looked legitimate, and wait for automated CI/CD pipelines to pull the poisoned package. No additional verification occurred between the attacker clicking "publish" and the malicious code running in production environments.

GitHub's response: staged publishing with mandatory 2FA verification. As of npm CLI 11.15.0, packages require a human maintainer to pass a 2FA challenge before any new version goes live. The package sits in a "staged" state until someone with the right credentials approves it.

Timeline

Initial compromise vector: Attackers used credential stuffing against accounts without 2FA enabled. Many maintainers reused passwords across services.

Publication: Malicious versions were published directly to the registry without delay or verification.

Detection window: Varied from hours to days. Some malicious packages accumulated significant download counts before removal.

Response: GitHub announced staged publishing and new install source flags. Organizations must opt into the protection by updating their CLI and configuring staged publishing for sensitive packages.

Which Controls Failed or Were Missing

Authentication controls: Single-factor authentication on maintainer accounts. No requirement for 2FA on high-impact packages.

Publication verification: No human-in-the-loop verification between a publish command and registry availability. An attacker with valid credentials could push code instantly.

Session management: Long-lived authentication tokens with no re-verification requirements for sensitive operations.

Dependency source controls: No mechanism to restrict package installations to registry-only sources. Developers could inadvertently install packages from git URLs or local paths without explicit approval.

Automated pipeline protections: CI/CD systems pulled packages automatically with no verification of publisher identity or publication authenticity.

What the Relevant Standards Require

NIST 800-53 Rev 5 addresses software supply chain security in multiple controls:

  • SR-3 (Supply Chain Controls and Processes): Requires processes to identify and address weaknesses in supply chain elements. The lack of publication verification represents a weakness in the supply chain process.

  • SR-4 (Provenance): Mandates documentation and verification of the development and delivery path for system components. Without staged publishing, you cannot verify that the person who published version 2.4.1 is the same person who published 2.4.0.

  • IA-2(1) (Multi-Factor Authentication to Privileged Accounts): Package maintainer accounts are privileged — they control code that runs in thousands of production environments. 2FA should not be optional.

ISO 27001 control 8.30 (Outsourced Development) requires verification of software integrity. When you consume npm packages, you are outsourcing development. You need controls to verify that what you download matches what the legitimate maintainer intended to publish.

OWASP Top 10 2021 lists A08:2021 – Software and Data Integrity Failures. The attack pattern described here is the textbook example: unsigned packages, no verification of publisher identity, no human checkpoint before code goes live.

Lessons and Action Items for Your Team

Update Your CLI Now

Staged publishing requires npm CLI 11.15.0 or newer. Check your version:

npm --version

If you are below 11.15.0, update immediately. The new install source flags and staged publishing features will not work on older versions.

Enable Staged Publishing for High-Impact Packages

Not every internal package needs staged publishing. Focus on:

  • Packages with more than 1,000 downloads per week
  • Packages used in production services
  • Packages that handle authentication, authorization, or sensitive data

Enable staged publishing in your package.json or through the npm registry settings. Test the workflow with your team — ensure everyone with publish rights has 2FA configured and knows how to approve staged releases.

Configure Install Source Flags

The new flags let you control where packages can be installed from. Add this to your .npmrc:

install-links=false
install-git=false

This blocks installations from local paths and git URLs unless you explicitly override. If your team needs git-based dependencies for internal tools, document which repositories are approved and create an exception process.

Audit Your Maintainer Accounts

List everyone with publish rights to your organization's packages. Remove accounts that:

  • Have not published in the last 12 months
  • Belong to former employees
  • Use email addresses on domains you do not control

Require 2FA for all remaining accounts. GitHub provides organization-level 2FA requirements — turn them on.

Update Your CI/CD Pipeline

If your pipeline publishes packages automatically, you will need to adjust for staged publishing. Options:

  1. Human approval step: Add a manual gate where a maintainer approves the staged package before it goes live. This is the most secure option.

  2. OIDC trusted publishing: Configure OpenID Connect authentication for your CI/CD pipeline. This allows automated publishing with cryptographic verification of the pipeline's identity. GitHub recommends this approach for teams that need automation without sacrificing security.

  3. Separate staging and production packages: Publish pre-release versions automatically, but require human approval for production releases.

Monitor for Suspicious Publications

Set up alerts for:

  • New versions published outside normal working hours
  • Publications from IP addresses outside your organization's ranges
  • Multiple rapid publications (possible sign of an attacker trying different payloads)

GitHub's audit logs show publication events. Export them to your SIEM or log analysis tool.

Test Your Rollback Procedure

If an attacker publishes a malicious version despite your controls, how quickly can you:

  1. Unpublish the malicious version
  2. Notify downstream consumers
  3. Publish a clean version

Document the procedure. Test it quarterly. Ensure everyone with publish rights knows how to execute it.

The npm ecosystem processes billions of package downloads per week. Staged publishing with 2FA does not eliminate supply chain risk, but it breaks the most common attack pattern: credential theft leading to instant malicious publication. Implement it for your critical packages this quarter.

Topics:Incident

You Might Also Like