npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept 2025) — Motivates GitHub Dependabot 'Cooldown' Mitigation
npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept (TL-2026-1714), also tracked as npm chalk/debug supply-chain attack, is a high-severity supply-chain compromise, first published 2026-07-27. It has no confirmed attribution, affects npm (open-source JavaScript ecosystem) chalk, maps to 21 MITRE ATT&CK techniques (T1027, T1041, T1056), and is covered by 9 detection rules and 35 indicators of compromise.
Key facts for TL-2026-1714
- Threat ID
- TL-2026-1714
- Also known as
- npm chalk/debug supply-chain attack, Qix npm account compromise, September 2025 npm crypto-clipper campaign
- Severity
- HIGH
- Status
- RESOLVED
- Category
- SUPPLY_CHAIN
- First published
- 2026-07-27
- Last reviewed
- 2026-07-27
- Attribution confidence
- LOW
- Motivation
- FINANCIAL
- Target sectors
- technology, software-development, financial-services
- Target regions
- Global
- Detection rules
- 9
- Indicators of compromise
- 35
Malware and tooling in npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept
Malware and tooling: npm crypto-clipper (window.stealthProxyControl payload)
On 2025-09-08, a phishing attack against npm maintainer Josh Junon ('Qix') led to malicious, wallet-hijacking versions of chalk, debug, and 17 other packages (>2B combined weekly downloads) being published to the npm registry; the payload rewrote cryptocurrency transaction destinations in browser contexts. Help Net Security (2026-07-27) cites this incident as the motivating case for GitHub's new Dependabot 'cooldown' feature, which delays non-security dependency-update PRs (default ~3 days) to let the community flag malicious releases before auto-merge.
How npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept works
On September 8, 2025 at approximately 13:00 UTC, an attacker sent a convincing 2FA-reset phishing email from the fraudulent domain npmjs[.]help to Josh Junon (npm handle 'Qix'), maintainer of the widely depended-upon chalk and debug packages. The email harvested Junon's npm credentials and a live TOTP code, giving the attacker full control of the account within minutes. At 13:16 UTC — roughly 16 minutes after compromise — the attacker began publishing trojanized versions of 18-19 high-traffic npm packages (chalk, debug, ansi-styles, ansi-regex, strip-ansi, wrap-ansi, slice-ansi, has-ansi, color-convert, color-string, color-name, color, simple-swizzle, is-arrayish, backslash, error-ex, supports-color, supports-hyperlinks, chalk-template), which collectively receive over 2 billion weekly downloads.
The injected payload was heavily obfuscated JavaScript that activated only in browser execution contexts (it deliberately no-opped in Node.js/server environments to reduce detection, occasionally throwing 'ReferenceError: fetch is not defined' during server-side builds — an incidental detection signal). In-browser, it hooked fetch(), XMLHttpRequest, window.ethereum.request, and Solana signing calls, then silently rewrote outbound cryptocurrency transaction recipients and token-approval targets to attacker-controlled wallet addresses across Ethereum, Bitcoin, Solana, Tron, Litecoin, and Bitcoin Cash. To evade visual inspection, the malware used Levenshtein-distance address substitution to select look-alike attacker addresses resembling the legitimate recipient, and specifically targeted ERC-20 function selectors for approve, transfer, transferFrom, and permit. A global object named window.stealthProxyControl was used to coordinate the hooked behavior, and a remote WebSocket endpoint (websocket-api2.publicvm[.]com) alongside two BunnyCDN-hosted domains (static-mw-host.b-cdn[.]net, img-data-backup.b-cdn[.]net) served as supporting infrastructure.
The community first raised suspicion around 14:16-15:20 UTC via Bluesky/GitHub; Junon publicly acknowledged the compromise at ~15:15-15:16 UTC. npm began takedown at 17:17 UTC, and all impacted chalk versions were removed from the registry by 19:59 UTC, with residual malicious versions of other packages cleaned up September 9. JFrog subsequently reported the campaign's scope extended beyond Qix's own packages. Despite the massive reach (an estimated 99% of scanned cloud environments contained at least one affected package pre-attack, ~10% contained the malicious code post-distribution), actual reported cryptocurrency theft was minimal given the short ~2-hour live window and rapid community detection.
Almost eleven months later, Help Net Security (2026-07-27) reports that GitHub has shipped a Dependabot 'cooldown' option (configurable via the `cooldown` key in `dependabot.yml`) that delays non-security dependency-update pull requests by a default window (the article cites 3 days) so that malicious package versions have time to be flagged by the community before automated tooling (including Dependabot itself) proposes the update. Security updates for known vulnerabilities bypass the cooldown. GitHub's Advisory Database recorded over 6,500 npm malware advisories in the year ending May 2026 (~18/day), underscoring that this chalk/debug incident is illustrative of an ongoing, high-frequency npm malicious-package problem rather than an isolated event.
MITRE ATT&CK techniques used in TL-2026-1714
Defense Evasion
T1027 Obfuscated Files or Information; T1140 Deobfuscate/Decode Files or Information; T1480 Execution Guardrails
Exfiltration
T1041 Exfiltration Over C2 Channel
Credential Access
T1056 Input Capture; T1621 Multi-Factor Authentication Request Generation
Execution
T1059 Command and Scripting Interpreter; T1204 User Execution
Command and Control
T1071 Application Layer Protocol
Collection
T1185 Browser Session Hijacking
Initial Access
T1195 Supply Chain Compromise; T1199 Trusted Relationship; T1566 Phishing
Impact
T1565 Data Manipulation; T1657 Financial Theft
Resource Development
T1583 Acquire Infrastructure; T1585 Establish Accounts; T1587 Develop Capabilities; T1608 Stage Capabilities
Reconnaissance
T1589 Gather Victim Identity Information; T1593 Search Open Websites/Domains
Affected products and versions in npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept
- npm (open-source JavaScript ecosystem) — chalk
Vulnerable versions: 5.6.1
Fixed in: registry-restored clean release post 2025-09-08 19:59 UTC takedown - npm (open-source JavaScript ecosystem) — debug
Vulnerable versions: 4.4.2
Fixed in: registry-restored clean release post 2025-09-09 cleanup - npm (open-source JavaScript ecosystem) — ansi-styles / ansi-regex / strip-ansi / wrap-ansi / slice-ansi / has-ansi
Vulnerable versions: ansi-styles@6.2.2; ansi-regex@6.2.1; strip-ansi@7.1.1; wrap-ansi@9.0.1; slice-ansi@7.1.1; has-ansi@6.0.1
Fixed in: registry-restored clean releases post cleanup - npm (open-source JavaScript ecosystem) — color-convert / color-string / color-name / color
Vulnerable versions: color-convert@3.1.1; color-string@2.1.1; color-name@2.0.1; color@5.0.1
Fixed in: registry-restored clean releases post cleanup - npm (open-source JavaScript ecosystem) — simple-swizzle / is-arrayish / backslash / error-ex / supports-color / supports-hyperlinks / chalk-template
Vulnerable versions: simple-swizzle@0.2.3; is-arrayish@0.3.3; backslash@0.2.1; error-ex@1.3.3; supports-color@10.2.1; supports-hyperlinks@4.1.1; chalk-template@1.1.1
Fixed in: registry-restored clean releases post cleanup
Remediation for npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept
Patches
- Pin dependencies to versions published before 2025-09-08 13:16 UTC or to the maintainer-restored clean releases published after the 2025-09-09 registry cleanup
Immediate actions
- Audit package-lock.json / yarn.lock / pnpm-lock.yaml / bun.lockb for the compromised package@version pairs published 2025-09-08 13:16 UTC through 2025-09-09 cleanup
- Delete node_modules and the local npm cache, regenerate lockfiles, and reinstall only verified clean versions of chalk, debug, ansi-styles, ansi-regex, strip-ansi, wrap-ansi, slice-ansi, has-ansi, color-convert, color-string, color-name, color, simple-swizzle, is-arrayish, backslash, error-ex, supports-color, supports-hyperlinks, and chalk-template
- Rotate API keys, tokens, and secrets used in any build/deploy environment that installed an affected package during the exposure window
- Block and alert on network indicators: npmjs[.]help, static-mw-host.b-cdn[.]net, img-data-backup.b-cdn[.]net, websocket-api2.publicvm[.]com, and IP 185.7.81.108
Workarounds
- Use `npm ci` instead of `npm install` to enforce lockfile-pinned, reproducible installs and prevent silent adoption of a newly-published compromised version
- Mirror critical/high-download dependencies through a private registry with pre-release vetting or the same cooldown-style delay Dependabot now offers natively
Longer-term hardening
- Enable GitHub Dependabot 'cooldown' (dependabot.yml `cooldown` key) to delay non-security dependency-update PRs by a default window so malicious releases are more likely to be caught before auto-merge
- Adopt Software Composition Analysis (SCA) scanning (e.g. Socket.dev, Semgrep, Snyk, Mend) in CI/CD with build-failure gates on known-malicious package versions
- Require phishing-resistant / hardware-key MFA for npm accounts maintaining high-download packages
- Rebuild and redeploy any application that shipped a bundle built during the exposure window, since server-side installs alone did not trigger the payload but bundled front-end code could have
Weaknesses (CWE) in npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept
CWE-506, CWE-829
Timeline of npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept
- Attacker registers the phishing domain npmjs[.]help, later used to impersonate npm support.
- All impacted chalk versions removed from the npm registry by 19:59 UTC.
- npm registry operators begin takedown of the malicious package versions at 17:17 UTC.
- Josh Junon publicly acknowledges the account compromise at approximately 15:15-15:16 UTC.
- Community members flag suspicious obfuscated code in the new releases on Bluesky and GitHub between roughly 14:16 and 15:20 UTC.
- First malicious package version published to npm at 13:16 UTC, roughly 16 minutes after account takeover; attacker proceeds to publish trojanized releases of 18-19 packages including chalk@5.6.1 and debug@4.4.2.
- Fraudulent 2FA-reset email sent from npmjs[.]help to chalk/debug maintainer Josh Junon ('Qix') at approximately 13:00 UTC, harvesting credentials and a live TOTP code.
- JFrog reports the malicious-package campaign extends beyond Qix's own packages; residual malicious versions of affected dependencies cleaned up registry-wide.
- Security vendors (Sygnia, Qualys, Wiz, Sonatype, Semgrep, Aikido, StepSecurity) publish detailed technical breakdowns of the payload, IOCs, and blast radius.
- Help Net Security reports GitHub has shipped a Dependabot 'cooldown' feature (configurable via dependabot.yml, default ~3-day delay on non-security update PRs) explicitly motivated by this incident, alongside GitHub Advisory Database figures of 6,500+ npm malware advisories in the trailing year (~18/day).
Sources cited for npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept
- GitHub Dependabot gets a cooldown to block npm-style supply chain attacks
- 16 Minutes to Impact: npm Supply Chain Abuse Deploys Crypto-Draining Malware
- Widespread npm Supply Chain Attack: Breaking Down Impact & Scope Across Debug, Chalk, and Beyond
- chalk, debug and color on npm compromised in new supply chain attack
- npm Chalk and Debug Packages Compromised
- npm debug and chalk packages compromised
- 20+ Popular NPM Packages Compromised (Chalk, Debug, Strip-ANSI, Color-Convert, Wrap-ANSI...)
- npm Supply Chain Attack: Massive Compromise of debug, chalk, and 16 Other Packages
- When Dependencies Turn Dangerous: Responding to the NPM Supply Chain Attack
- Version 5.6.1 published to npm is compromised (RESOLVED)
- Questions on scope and impact of npm malware advisories (2025-09-09)
- GHSA-2v46-p5h4-248w — chalk malicious code advisory
- GHSA-8mgj-vmr8-frr6 — debug malicious code advisory
- GHSA-p5rr-crjh-x7gr — ansi-styles malicious code advisory
Threats related to npm Supply-Chain Compromise (chalk/debug + 17 packages, Sept
Detection coverage for TL-2026-1714
As of 2026-07-27, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1714 across Splunk SPL, Microsoft KQL and Sigma, covering 35 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.