Sonatype Research Labs discovered hidden runtime loaders in 12 npm releases across 10 hijacked packages. These loaders decode payload-server IP addresses from Ethereum transactions and execute hidden JavaScript. Notably, the package manifests lack consumer install or postinstall hooks.
This breaks a common assumption. Many teams address npm supply chain risk by blocking lifecycle scripts. While effective, this wouldn't have stopped this threat.
So, where should your next defensive effort go? This guide helps you decide using a decision tree.
The Decision You Are Facing
Your current npm practices might include lockfiles, --ignore-scripts in CI, and a vulnerability scanner. Yet, these won't catch a dormant loader in library code that activates during runtime.
The key question is which control layer to prioritize: pre-admission (what enters your codebase), build-time (how your pipeline handles it), or runtime (what the code does when running). You likely can't fund all three at once. Choose based on the factors below.
Key Factors That Affect Your Choice
Consider these factors before deciding on a path.
1. Where does your code execute? If it runs on servers with secrets, cardholder data, or production credentials, runtime behavior is critical. Execution without an install hook means malicious code runs with your application's privileges.
2. How much do you control egress? The loader connects to a payload server with an address decoded from Ethereum transactions. If your servers can connect to any internet host, the attack proceeds. If egress is allow-listed, the attack stalls.
3. Do you pin and review dependency updates? A hijacked package can appear as a normal new release. If updates flow automatically, you've outsourced admission control to the maintainer's account.
4. What are your audit obligations? If you're under PCI DSS, SOC 2, or ISO 27001, you need documented, evidenced controls, not just intentions.
Path A: Pre-admission Control
Choose this if: updates flow automatically, you lack a review gate for new versions, and your app runtimes are too varied to instrument quickly.
If you can't answer "who approved this version and why?" for a dependency, start here.
What it looks like:
- Pin exact versions and commit lockfiles. Fail CI on lockfile drift.
- Add a cooldown on new releases before adoption, so hijacked versions can be flagged.
- Diff dependency updates, not just versions. A patch release adding network calls or obfuscated blobs needs a human review.
- Maintain an internal inventory (SBOM) to quickly answer "are we running any of the 12 affected releases?"
Requirements driving this path: PCI DSS Requirement 6.3.2 calls for an inventory of software components. ISO 27001 Annex A control 5.21 covers managing information security in the ICT supply chain. SOC 2 change management criteria (CC8.1) expect authorized, reviewed changes.
Limit: Admission review catches what's visible. A well-obfuscated loader can pass a quick diff. This path reduces exposure but doesn't eliminate it.
Path B: Build-time and Pipeline Control
Choose this if: you already pin versions, but your CI/CD has broad network access and lacks automated analysis of dependencies.
If your pipeline installs packages and builds artifacts without inspecting contents, go here.
What it looks like:
- Run behavioral and static analysis on dependencies, looking for hidden or encoded strings, dynamic execution of fetched content, and blockchain RPC calls.
- Treat any library contacting an Ethereum node as an anomaly unless it's a web3 library. Ethereum transactions as a dead-drop for configuration is unusual in general-purpose packages.
- Keep
--ignore-scriptson, but don't rely on it as the sole defense. - Isolate build runners. Restrict outbound traffic from CI to your registry mirror and known hosts.
Requirements driving this path: PCI DSS Requirement 6.2.4 expects software engineering techniques that prevent common attacks, and Requirement 6.3.1 requires managing vulnerabilities, including from third-party components. NIST CSF v2.0 includes supply chain risk management under Govern. NIST 800-53 Rev 5 SR-3 and SI-7 address supply chain controls and software integrity.
Limit: Build-time analysis sees code at rest. A loader deciding its behavior at runtime may look benign in static review.
Path C: Runtime and Egress Control
Choose this if: your production workloads hold sensitive data, you've invested in Paths A and B, or you need a control for malicious packages already in your codebase.
If you must assume a bad dependency will eventually run, this is your backstop.
What it looks like:
- Default-deny egress from application servers and containers. Allow-list legitimate destinations. A decoded payload-server IP not on the list gets dropped.
- Alert on outbound connections to blockchain RPC providers from services without a business reason to use them.
- Run workloads with least privilege: read-only filesystems, no ambient cloud credentials, scoped secrets.
- Log process and network telemetry to track what a library did, not just which version you had.
Requirements driving this path: PCI DSS Requirements 1.3 and 1.4 govern restricting network traffic. Requirement 10 covers logging and monitoring. SOC 2 CC6.6 and CC7.2 address boundary protection and anomaly monitoring. ISO 27001 Annex A control 8.20 covers network security.
Limit: This path is operationally expensive and may generate noise initially. It doesn't identify bad packages; it only contains the damage.
Summary Matrix
| Factor | Path A: Pre-admission | Path B: Build-time | Path C: Runtime/egress |
|---|---|---|---|
| Best when | Updates flow in unreviewed | Pipeline lacks content inspection | Production holds sensitive data |
| Stops hijacked release from entering | Partly | Partly | No |
| Catches loader without install hook | Only if visible in diff | If detectable statically | Yes, at the network layer |
| Contains damage if it runs | No | No | Yes |
| Effort to start | Low | Medium | High |
| Key requirements | PCI DSS 6.3.2; ISO 27001 5.21; SOC 2 CC8.1 | PCI DSS 6.2.4, 6.3.1; NIST CSF GV.SC; NIST 800-53 SR-3, SI-7 | PCI DSS 1.3, 1.4, 10; SOC 2 CC6.6, CC7.2; ISO 27001 8.20 |
The short version: Start with Path A if you have no admission gate, as it's cost-effective and provides the inventory needed for other controls. Add Path C early for handling secrets or payment data, as it's the only layer effective after a loader slips through. Path B fills the gap between them. No single path is sufficient, but prioritize based on your current weaknesses.





