Overview of the ChainDrop npm Worm
A self-propagating malicious campaign known as the ChainDrop worm successfully infected over 400 npm packages, impacting components downloaded hundreds of millions of times weekly. According to an analysis by Unit 42, the campaign compromised widely utilized modules such as keyv and cacheable-request. The adversaries leveraged stolen npm publishing tokens and automated propagation techniques to distribute trojanized packages while preserving original functionality, presenting a severe risk to downstream software consumers, developer endpoints, and continuous integration environments.
Technical Analysis of the Attack Chain
Infection and Execution Vector
The malicious packages maintain their expected functionality alongside subtle modifications designed to initiate the infection sequence. The core alteration exists within the package manifest (package.json), where the threat actors insert a preinstall lifecycle hook. This command executes setup.mjs, a lightweight dropper script.
The dropper verifies whether the Bun JavaScript runtime is present on the host system PATH. If missing, it downloads a clean, legitimate release of Bun from the official GitHub repository, using it as a portable execution vehicle rather than exploiting the runtime itself. The script then executes an obfuscated JavaScript payload designated as math_init.js.
Evasion and Propagation Mechanisms
To avoid detection and maintain operational security, the malware incorporates several environmental checks:
- Locale Filtering: The worm checks system language settings and terminates cleanly if a Russian-language environment is detected.
- Execution Context: When executed on local developer machines, the payload spawns a detached background process to allow normal installation to complete without error prompts. In continuous integration (CI) environments, it executes inline.
- Infrastructure Management: Researchers observed the operators reconfiguring the entire command-and-control (C2) infrastructure via a single Ethereum transaction without modifying the deployed malware.
Credential Harvesting and Memory Scraping
Once active, the worm systematically sweeps the host environment to gather system telemetry, npm tokens, and GitHub credentials necessary for further propagation. Notably, the malware employs an embedded Python helper to target live process memory on GitHub Actions runners. By reading /proc/<pid>/maps and /proc/<pid>/mem, the helper inspects the Runner.Worker process memory to extract ephemeral OpenID Connect (OIDC) tokens and runner secrets before they can be purged naturally at the end of a job.
Persistence is established through multiple vectors, including malicious Visual Studio Code workspace tasks configured to execute automatically upon directory initialization.
Actionable Mitigations
Defenders and maintainers must prioritize securing their development pipelines and dependency trees against automated supply chain threats:
- Dependency Auditing: Regularly review project dependencies for unauthorized modifications, unexpected lifecycle scripts (such as
preinstallhooks), and unverified package versions. - Token Rotation: Immediately revoke and rotate all npm publishing tokens, GitHub tokens, and cloud credentials associated with environments that interacted with potentially compromised packages.
- CI/CD Hardening: Restrict permissions on CI/CD runners, minimize the storage of sensitive secrets in environment variables where memory scraping could expose them, and implement strict least-privilege access models for non-human identities.
Related: Fake Paysafe/Skrill SDKs on npm & PyPI Steal Credentials, Keyv npm Supply-Chain Attack: Worm Infection and Dead-Man Switch