{"slug": "chaindrop-a-supply-chain-worm-stealing-credentials-and-self-propagating-via-npm", "title": "ChainDrop: A Supply Chain Worm Stealing Credentials and Self-Propagating via Legitimate Provenance-Signed npm Packages", "summary": "Aikido Security disclosed a critical npm supply chain attack dubbed ChainDrop, which compromised popular packages including keyv, flat-cache, and file-entry-cache. The attackers hijacked maintainer GitHub accounts, injected malicious preinstall scripts, and used legitimate GitHub Actions to publish provenance-signed versions that steal credentials and self-propagate via stolen npm and GitHub tokens.", "body_md": "#\nChainDrop: A Supply Chain Worm Stealing Credentials and Self-Propagating via Legitimate Provenance-Signed npm Packages\n\n##\n1. Basic Information\n\n-\n**Article Title**: Keyv and friends compromised in active Shai-Hulud supply chain attack\n-\n**Publisher**: Aikido Security\n-\n**Publication Date**: August 4, 2026\n-\n**Original Source**: [Aikido Security](https://www.aikido.dev/blog/keyv-and-friends-compromised-in-npm-supply-chain-attack)\n-\n**Related Sources**: [BleepingComputer](https://www.bleepingcomputer.com/news/security/massive-chaindrop-npm-supply-chain-attack-infects-hundreds-of-packages/)\n-\n**Related Malware**: ChainDrop, Shai-Hulud worm family, `setup.mjs`\n\n, `Math_Symbol.js`\n\n, `math_init.js`\n\n-\n**Related Products & Services**: npm, GitHub Actions, Bun, AWS, Kubernetes, HashiCorp Vault, Stripe, Slack, VS Code, Claude Code\n-\n**Main Compromised Packages**: `keyv`\n\n6.0.0, `flat-cache`\n\n6.1.24, `file-entry-cache`\n\n11.1.6, `cacheable-request`\n\n13.0.20, and others\n-\n**Severity**: Critical\n\nInitial reports showed 434 packages and 1,381 versions affected, totaling over 2 billion downloads per month. Attackers compromised the maintainers' GitHub accounts, pushed malicious files directly to the main branch, and published them to npm using legitimate GitHub Actions. As a result, the compromised versions also received valid provenance.\n\n##\n2. Summary\n\nThis attack uses `preinstall`\n\nscripts in compromised npm packages to run Bun and a credential-stealing worm. It steals secrets from GitHub, npm, AWS, Kubernetes, Vault, and other services. At the same time, it uses the stolen tokens to self-propagate to other packages and GitHub repositories.\n\n##\n3. Attack Flow\n\n###\nChain A: Compromising Development Environments via Legitimate Packages\n\n- The attacker compromises a Keyv maintainer's GitHub account.\n- They add\n`setup.mjs`\n\n, `Math_Symbol.js`\n\n, and the `preinstall`\n\nscript in `package.json`\n\ndirectly to the main branch.\n- Legitimate GitHub Actions build and publish the new version to npm.\n- A user or CI system runs\n`npm install`\n\non the compromised version.\n-\n`setup.mjs`\n\nruns automatically as a `preinstall`\n\nscript.\n- It downloads Bun 1.3.13 from the official GitHub Release.\n- It runs the obfuscated\n`Math_Symbol.js`\n\nusing Bun.\n- It deletes the temporary Bun directory.\n\n###\nChain B: Credential Collection and Exfiltration\n\n- It lists tokens and keys for npm, GitHub, AWS, Kubernetes, Vault, Stripe, Slack, and others.\n- On GitHub Actions runners, it dumps secret stores from process memory.\n- It searches IMDS, ECS metadata, AWS Secrets Manager, the Kubernetes API, and Vault KV.\n- It checks about 200 globs for\n`.env`\n\nfiles, SSH keys, Terraform state, Docker credentials, VPN settings, and more.\n- It encrypts the collected data using the attacker's public RSA key.\n- It uploads the data to a public GitHub repository with the description\n`Shai-Hulud: Here We Go Again`\n\n.\n- If the upload fails, it sends the data to\n`npm-cache[.]com`\n\n, resolved via an Ethereum smart contract.\n\n###\nChain C: Self-Propagation\n\n- It checks the permissions of stolen npm tokens using endpoints like\n`/-/npm/v1/tokens`\n\n.\n- It downloads the current tarball for each publishable package.\n- It bumps the patch version and injects\n`preinstall`\n\n, `setup.mjs`\n\n, and `math_init.js`\n\n.\n- It republishes the compromised version to npm.\n- If it finds a\n`ghs_`\n\ntoken, it commits changes to up to 50 branches.\n- It adds auto-execution hooks to\n`.claude/settings.json`\n\nand `.vscode/tasks.json`\n\n.\n- When developers open the repository in VS Code or Claude Code, the attack runs again.\n\n##\n4. Attacker Positions and Execution Locations\n\n-\n**Initial Attacker**: Operates the legitimate repository using a compromised GitHub maintainer account.\n-\n**Distribution Points**: GitHub Actions and the npm registry.\n-\n**Execution Locations**: Developer workstations, CI runners, containers, and cloud VMs.\n-\n**Credential Search Targets**: Local filesystem, process memory, AWS metadata, Kubernetes API, and Vault API.\n-\n**Exfiltration Destinations**: Public GitHub repository and the fallback domain `npm-cache[.]com`\n\n.\n-\n**Propagation Targets**: npm packages and GitHub repositories/branches where the token has publish permissions.\n\n##\n5. Visibility for Victims and Administrators\n\nTo users, the attack looks like a normal dependency update or `npm install`\n\n. Because the packages have legitimate maintainer names, normal workflows, and valid provenance, digital signatures alone cannot identify the malicious behavior. SOCs and development platform administrators can spot the attack through actions like downloading Bun during an installation, Node/Bun searching for extensive secrets, the creation of many repositories on GitHub, suspicious patch releases of packages, and commits labeled `chore: update config`\n\n.\n\n##\n6. Success and Failure Conditions\n\n###\nSuccess Conditions\n\n- The compromised version is resolved in dependencies.\n- Lifecycle scripts are allowed to run.\n- Valid tokens or cloud credentials exist on the runner or workstation.\n- Tokens have permissions to publish packages, write to repositories, and read secrets.\n- Network egress is allowed to GitHub or the fallback domain.\n\n###\nFailure Conditions\n\n- Lockfiles are pinned to a known safe version to block the compromised version.\n- Unnecessary lifecycle scripts are disabled using flags like\n`--ignore-scripts`\n\n.\n- Short-lived, least-privilege tokens are used, and no long-term secrets are stored on runners.\n- Bun downloads or secret-store access are blocked during package installation.\n- Compromised tokens are revoked immediately, and publishing permissions on npm and GitHub are restricted.\n\n##\n7. What Happens on Success\n\nSecrets in development and CI environments are stolen across the board, allowing follow-on access to AWS, Kubernetes, Vault, npm, and GitHub. Furthermore, because the stolen public and repository tokens are used to compromise other legitimate software, the impact can grow exponentially from a single device to organizations, customers, and downstream dependencies.\n\n##\n8. Observable Logs\n\n###\nEmail\n\n- Unclear if the initial GitHub account compromise involved phishing.\n- Login and token generation notifications from GitHub and npm.\n\n###\nProxy / SWG / DNS\n\n`github.com/oven-sh/bun/releases/download/bun-v1.3.13/`\n\n- Repeated access to\n`registry.npmjs.org/-/whoami`\n\nand token/package APIs.\n- Metadata requests to\n`169.254.169.254`\n\nand `169.254.170.2`\n\n.\n-\n`npm-cache[.]com:443/router`\n\n.\n- Ethereum RPC calls and lookups to specific contracts.\n\n###\nEndpoint / EDR\n\n-\n`npm install`\n\n→ `node setup.mjs`\n\n→ Bun → `Math_Symbol.js`\n\n/`math_init.js`\n\n.\n- Reading of runner process memory.\n- Heavy access to\n`.npmrc`\n\n, `.aws`\n\n, `.kube`\n\n, `.vault-token`\n\n, `.env`\n\n, and SSH keys.\n- Modifications to\n`.claude/settings.json`\n\nand `.vscode/tasks.json`\n\n.\n- Creation and deletion of temporary Bun directories.\n\n###\nIdentity / IdP\n\n- Abnormal logins to GitHub maintainer accounts.\n-\n`whoami`\n\nchecks and new releases using npm/GitHub tokens.\n- Secret enumeration from unusual principals or runners in AWS, Kubernetes, or Vault.\n\n###\nSaaS / Cloud\n\n- GitHub repository descriptions reading\n`Shai-Hulud: Here We Go Again`\n\n.\n- Abnormal use of GitHub Actions OIDC tokens.\n- Multi-region execution of AWS\n`ListSecrets`\n\n.\n- Bulk retrieval of Kubernetes namespace secrets.\n- Vault mount enumeration and full KV reads.\n\n###\nNetwork\n\n- Fan-out traffic to GitHub, npm, and cloud APIs immediately after installation.\n- Egress from CI runners to unusual RPC endpoints or domains.\n\n##\n9. Determining Attack Success\n\n-\n**Contact Only**: The compromised version appears in lockfiles or registry logs, but no installation occurred.\n-\n**User Action**: A developer or CI system installs the target version.\n-\n**Initial Execution**: The process chain of `setup.mjs`\n\n, Bun, and malicious scripts is confirmed.\n-\n**Malware Success**: Access to secret files, metadata, or process memory is confirmed.\n-\n**Data Exfiltration**: Encrypted bundles are sent to GitHub or the fallback domain, and stolen tokens are used in the cloud.\n-\n**Follow-on Compromise**: Unauthorized npm releases, commits to multiple branches, or access to other cloud resources are confirmed.\n\n##\n10. Investigation Playbook\n\n###\nTrigger\n\n- SBOM or lockfile matches the target package/version.\n- Presence of\n`setup.mjs`\n\n, `Math_Symbol.js`\n\n, or `math_init.js`\n\n.\n- Bun downloaded during installation.\n- The\n`Shai-Hulud: Here We Go Again`\n\nrepository.\n\n###\nInitial Checks\n\n- Determine the installation time, host/runner, and executing user.\n- Preserve package caches, lockfiles, CI artifacts, and process/network logs.\n- Inventory all secrets and permissions that existed in that environment.\n\n###\nWorkstation / CI\n\n- Check process trees, filesystem access, and memory dump traces.\n- Inspect\n`.claude/settings.json`\n\n, `.vscode/tasks.json`\n\n, and changes across all branches.\n- Check temporary Bun directories and script hashes.\n\n###\nAuthentication / Cloud\n\n- Revoke npm and GitHub tokens and check publishing history.\n- Investigate enumeration and read activities in AWS CloudTrail, Kubernetes audits, and Vault audits.\n- Correlate Actions OIDC subjects/audiences with cloud usage after issuance.\n\n###\nFollow-on Operations\n\n- Cross-check all packages and repositories that were open to publication.\n- Identify downstream consumers and artifacts.\n- Verify whether unauthorized roles, keys, workflow files, or package versions remain after rotating secrets.\n\n###\nContainment\n\n- Block compromised versions in registries and proxies.\n- Revoke all tokens, keys, and sessions at once.\n- Isolate and rebuild affected runners and workstations.\n- Revert package releases and commits, and republish safe versions.\n\n##\n11. Defense and Detection Ideas\n\n###\nSingle Events\n\n- Bun downloaded from an npm lifecycle script.\n- Process memory read by a CI runner.\n- Unexpected changes to\n`.claude/settings.json`\n\nor `.vscode/tasks.json`\n\n.\n- Distinctive strings in GitHub repository descriptions.\n\n###\nTimeline Correlation\n\n`npm install`\n\n→ `setup.mjs`\n\n→ Bun → secret store fan-out → GitHub upload → npm publish / multi-branch commit.\n\n###\nHunting Perspectives\n\n- Check specified packages/versions and all transitive dependencies.\n- Commits with the message\n`chore: update config`\n\nauthored by `claude`\n\n.\n- Post-installation\n`ListSecrets`\n\n, Kubernetes secret listing, and Vault mount enumeration.\n- Rapid release of multiple packages using a single token.\n\n###\nLog Gaps\n\n- Package installation and lifecycle script logs.\n- Runner process, file, and network telemetry.\n- npm publish audit logs.\n- GitHub branch protection bypass and commit audit logs.\n- Vault and Kubernetes secret read audit logs.\n\n###\nPriority Actions\n\n- Stop using the target version and create an inventory of all environments.\n- Rotate all secrets in environments where the package was installed.\n- Make CI tokens short-lived and enforce the principle of least privilege.\n- Treat provenance as evidence of the build path, not as a guarantee of safety.\n- Make IDE and AI agent configuration files subject to code owners and reviews.\n\n##\n12. Facts / Inference / Hypothesis\n\n###\nFacts\n\n- Malicious files were pushed to the main branch from a Keyv maintainer's GitHub account and published via legitimate workflows.\n-\n`preinstall`\n\nscripts execute Bun and credential-stealing scripts.\n- Secrets targeted include those for npm, GitHub, AWS, Kubernetes, and Vault.\n- Encrypted bundles are sent to GitHub, and stolen tokens are used to propagate to npm packages and GitHub repositories.\n\n###\nInference\n\n- Valid provenance does not guarantee maintainer intent or code safety.\n- If a package is installed, it is safest to treat all secrets present in that environment at the time as compromised, even without IOC matches.\n\n###\nHypothesis\n\n- Correlating package manager data, EDR logs, and cloud audits around the installation time can reconstruct the scope of a compromise based on secret usage even before endpoint detection.\n\n##\n13. MITRE ATT&CK Mapping\n\n###\nHigh Confidence\n\n-\n**T1195.002** Compromise Software Supply Chain\n-\n**T1059.007** JavaScript/JScript\n-\n**T1552.001** Credentials In Files\n-\n**T1552.005** Cloud Instance Metadata API\n-\n**T1555** Credentials from Password Stores\n-\n**T1528** Steal Application Access Token\n-\n**T1530** Data from Cloud Storage Object\n-\n**T1027** Obfuscated Files or Information\n-\n**T1567.001** Exfiltration to Code Repository\n\n###\nMedium Confidence\n\n-\n**T1555.006** Cloud Secrets Management Stores\n-\n**T1098** Account Manipulation\n-\n**T1078** Valid Accounts\n-\n**T1102.003** One-Way Communication (depending on details of public repository/contract usage)\n\n##\n14. Unknowns and Further Investigation\n\n- Initial compromise vector for maintainer accounts.\n- Total final number of compromised packages and versions.\n- Number of secrets actually decrypted and abused.\n- Attribution of the attackers.\n- Scope of deletions and revocations by npm and GitHub.\n- Installation and downstream impacts on organizations globally.\n\n##\n15. Impact on SOCs and General Organizations\n\nEven organizations that do not write Node.js code directly can still be affected through transitive dependencies introduced via frontend builds, CI tools, or outsourced SaaS development. SOCs, PSIRTs, development platforms, and cloud operations teams must not work in silos. They need to use the installation time as a common axis to integrate investigations across endpoints, CI environments, GitHub/npm, and cloud secret usage.\n\n##\n16. Summary\n\n###\nFor SOCs\n\n- Do not stop at matching target versions; correlate installation → Bun → secret access → cloud usage.\n- Check for metadata, Secrets Manager, Kubernetes, and Vault access from runners.\n- Investigate self-propagation to GitHub and npm across the board.\n\n###\nFor Administrators\n\n- Block compromised versions and rotate all secrets in environments where they were installed.\n- Minimize CI token scopes and OIDC permissions.\n- Protect IDE and AI agent configuration files.\n\n###\nFor Users\n\n- If there is any chance you installed the target package, do not assume it is clean. Preserve workstation and repository information and report it immediately.", "url": "https://wpnews.pro/news/chaindrop-a-supply-chain-worm-stealing-credentials-and-self-propagating-via-npm", "canonical_source": "https://dev.to/anoymask/chaindrop-a-supply-chain-worm-stealing-credentials-and-self-propagating-via-legitimate-351", "published_at": "2026-08-05 02:54:17+00:00", "updated_at": "2026-08-05 03:09:17.500744+00:00", "lang": "en", "topics": ["ai-safety", "ai-policy", "ai-ethics"], "entities": ["Aikido Security", "npm", "GitHub", "Bun", "AWS", "Kubernetes", "HashiCorp Vault", "Stripe"], "alternates": {"html": "https://wpnews.pro/news/chaindrop-a-supply-chain-worm-stealing-credentials-and-self-propagating-via-npm", "markdown": "https://wpnews.pro/news/chaindrop-a-supply-chain-worm-stealing-credentials-and-self-propagating-via-npm.md", "text": "https://wpnews.pro/news/chaindrop-a-supply-chain-worm-stealing-credentials-and-self-propagating-via-npm.txt", "jsonld": "https://wpnews.pro/news/chaindrop-a-supply-chain-worm-stealing-credentials-and-self-propagating-via-npm.jsonld"}}