Skip to main content
Two npm Packages Hijacked in One WeekIncident
4 min readFor DevOps Leaders

Two npm Packages Hijacked in One Week

On January 13, 2025, AsyncAPI discovered that several of its npm packages had been compromised and were distributing malware. Three days later, Jscrambler reported a similar incident affecting its packages. Both attacks delivered the Miasma malware framework to developers who installed what they believed were legitimate updates.

Timeline

AsyncAPI incident:

  • Attacker exploited a known configuration vulnerability in a GitHub Actions CI/CD workflow.
  • Malicious packages published to npm registry.
  • AsyncAPI team detected the compromise on January 13, 2025.
  • Affected packages removed; credentials rotated.

Jscrambler incident:

  • Leaked npm publishing credentials used to push malicious packages.
  • Source of credential leak remains unclear.
  • Compromise discovered January 16, 2025.
  • Malicious versions unpublished; new credentials issued.

Both attacks deployed the same Miasma malware framework, suggesting either a coordinated campaign or a shared toolset among attackers.

Which Controls Failed

AsyncAPI: Workflow permission controls

The GitHub Actions workflow ran with excessive permissions. The attacker exploited this to publish packages without additional authentication. This represents a failure in least-privilege access control.

Jscrambler: Credential exposure and rotation

npm publishing credentials leaked outside the organization. Whether through accidental commit, compromised developer machine, or third-party breach, the credential remained valid long enough for exploitation.

Both: Package signing and verification

Neither project had implemented package signing that would allow downstream consumers to cryptographically verify package authenticity. When malicious versions appeared, there was no technical mechanism for automated detection.

Both: Monitoring and alerting

The compromises went undetected until after malicious packages reached the registry. Neither organization had real-time alerts for unexpected package publications.

What the Standards Require

NIST 800-53 Rev 5 addresses several of these failures:

  • AC-6 (Least Privilege): "Each process executes with the least privilege necessary." Your CI/CD workflows should use scoped tokens that can only publish specific packages, not organization-wide credentials.

  • IA-5(1) (Password-Based Authentication): Requires periodic credential rotation. If you're using static npm tokens, you're already out of compliance.

  • SI-7 (Software, Firmware, and Information Integrity): "Employ integrity verification tools to detect unauthorized changes." This maps directly to package signing and verification.

ISO/IEC 27001:2022 Control 8.32 (Change Management) requires documented procedures for changes to production systems. Publishing a package is a production change. If your CI/CD pipeline can publish without approval gates, you don't meet this control.

SLSA Framework Level 2 (not a compliance standard but increasingly referenced in contracts) requires:

  • Version-controlled build scripts.
  • Authenticated build service.
  • Provenance generation for all packages.

Neither project met SLSA Level 2, which would have made the attacks significantly harder.

Lessons and Action Items

For your CI/CD pipelines:

  1. Audit GitHub Actions permissions now. Open .github/workflows/*.yml and check every permissions: block. If you see write-all or missing permission declarations, you're vulnerable. Set explicit, minimal permissions for each job.

  2. Use environment protection rules. GitHub lets you require manual approval for deployments to specific environments. Create a production environment, require approval from two maintainers, and configure your publish workflow to target that environment.

  3. Implement scoped tokens. npm supports granular access tokens that can only publish specific packages. Replace any organization-wide tokens with package-scoped tokens. Rotate them every 90 days.

For credential management:

  1. Scan your git history. Run git log -p | grep -i "npm_token\|NPM_TOKEN" across all repositories. If you find anything, assume it's compromised. Rotate immediately and audit recent package publications.

  2. Enable npm two-factor authentication. Require 2FA for all accounts with publish permissions. This won't stop a workflow compromise but will limit credential theft impact.

  3. Use short-lived tokens. If your CI/CD platform supports OIDC (GitHub Actions does), configure it to request temporary tokens from npm at build time instead of storing static credentials.

For package integrity:

  1. Sign your packages. npm supports package signatures via npm sign. Implement signing in your publish workflow and document the verification process for consumers.

  2. Generate provenance. Use npm publish --provenance to create SLSA provenance attestations. This creates a verifiable link between your source repository and published package.

  3. Monitor the registry. Set up alerts for unexpected package publications. Tools like Socket.dev and Snyk can monitor your organization's packages and alert on suspicious changes.

For detection:

  1. Alert on publish events. Configure webhooks or use npm's audit log API to send real-time notifications when packages are published. A human should review every publication within one hour.

  2. Diff package contents. Before each publish, generate a manifest of files and hashes. Store it in version control. After publication, download the package and verify the contents match. Alert on any discrepancy.

  3. Test in isolation first. Publish to a private registry or use npm pack to generate the tarball locally. Install it in a clean environment and verify functionality before pushing to the public registry.

The AsyncAPI and Jscrambler incidents weren't sophisticated zero-days. They exploited known configuration weaknesses and credential management failures. The same vulnerabilities likely exist in your pipelines right now. Start with the permission audit; it takes 30 minutes and eliminates the most common attack vector.

SLSA Framework

Topics:Incident

You Might Also Like