Skip to main content

On This Page

Secure Your Node.js Workflow Against Shai-Hulud Worms with np-audit

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

Stop letting npm install run untrusted code on your machine — meet np-audit

Developers frequently run npm install without realizing it grants full code execution to every maintainer in the dependency tree. The Shai-Hulud worm family exploited this in November 2025 to compromise over 700 packages and harvest 14,000 developer secrets in under 48 hours.

Why This Matters

While --ignore-scripts is the standard security recommendation, it is technically impractical because it breaks essential packages like bcrypt, sharp, and puppeteer. This creates a reality where developers choose between a broken build and total exposure to supply chain attacks. The technical reality is that npm lifecycle scripts are a “feature” that functions as a loaded gun, allowing attackers to exfiltrate AWS keys and GitHub tokens via legitimate-looking GraphQL API calls. Using static analysis to gate these scripts is the only way to maintain functionality while mitigating industrial-scale exploitation.

Key Insights

  • Shai-Hulud variants use three-line preinstall scripts to execute malicious setup.mjs files before any human review (2025).
  • Attackers use the Bun runtime to bypass Node-pattern detection during secret harvesting (Shai-Hulud, 2025).
  • TeamPCP campaigns include locale-based guardrails to skip systems with Russian language settings (2025).
  • Static analysis via np-audit flags eval(), high-entropy strings, and child_process spawning without requiring runtime dependencies.
  • Supply chain attacks have historically targeted high-profile packages including event-stream, ua-parser-js, and the Bitwarden CLI (2018-2025).
  • The np-audit tool functions by downloading tarballs and scoring scripts based on obfuscation patterns like hex escape density.

Working Examples

The standard preinstall hook used by Shai-Hulud worms to execute arbitrary code.

{
  "scripts": {
    "preinstall": "node setup.mjs"
  }
}

Installation and usage of the npa CLI to audit scripts before execution.

npm install -g np-audit
npa install
npa i --review

Practical Applications

  • GitHub Actions integration using npa ci to block builds if transitive dependencies are compromised.
  • Pitfall: Relying solely on —ignore-scripts which often results in broken native addons and toolchains like node-sass.
  • Use Case: Interactive review with npa i —review for manual informed consent of lifecycle scripts.
  • Pitfall: Failing to detect obfuscated payloads like var _0x3f2a or String.fromCharCode() chains in third-party install scripts.
  • Use Case: Setting a shell alias with npa alias —install to ensure every npm install is automatically scanned.

References:

Continue reading

Next article

Engineering Safe AI Agents: Why the First Paid Call Must Be Boring

Related Content