The qix compromise (Sept 2025): how 2.6 billion weekly downloads got hit
One email, billions of downloads
On 8 September 2025, the npm account of a maintainer known as qix was compromised. Within a short window, malicious versions of around 18 extremely popular packages — among them chalk and debug — were published to the registry. Those packages together see over 2.6 billion downloads a week. For roughly two hours, anyone installing or building against the latest versions could have pulled in tampered code.
It is one of the largest npm supply-chain incidents to date, and the entry point was almost mundane.
How it happened
The maintainer was phished. He received an email that looked like a legitimate npm notice, spoofing the branding and warning that his two-factor credentials were about to expire, with a prominent 'update 2FA now' link. The link led to a convincing fake login page. With those credentials, the attacker took over the account and published the malicious releases under a trusted name.
No zero-day, no clever exploit of npm itself — just a well-made phishing email reaching one person who maintains code the entire ecosystem depends on.
What the malicious code did
The injected payload was a crypto-clipper: code designed to run in users' browsers and quietly swap cryptocurrency wallet addresses during transactions, redirecting funds to the attacker. By most accounts the actual financial damage was small, because the community spotted and removed the bad versions fast — the malicious releases were live for only about two hours before being pulled. The scare was the scale, not the loss.
Why this matters even if you never use those packages directly
The uncomfortable part of supply-chain risk is transitivity. You may never list chalk or debug in your own dependencies, yet they sit deep inside packages you do use. A tiny utility with billions of downloads is exactly the kind of thing that ends up in everyone's tree without anyone choosing it. That is the whole point of a supply-chain attack: compromise one widely-trusted link and you reach everything built on top of it.
The practical lessons
- Use a lockfile and commit it. A
package-lock.jsonpins exact versions and hashes, so a fresh malicious 'latest' does not silently land in your build. - Do not auto-update blindly. Let new releases age before adopting them; many supply-chain payloads are caught within hours, so a short delay is real protection.
- Pin and review. Know what is in your tree, and treat a sudden new version of a deep dependency as something to look at, not wave through.
- Verify what you actually ship. The end of this chain is the code that reaches your users' browsers — that is what an attacker is ultimately after.
None of this is a knock on the maintainer
It is worth saying plainly: a phishing email that convincing could catch anyone, and open-source maintainers carry enormous load for little reward. The takeaway is not to blame a person — it is that depending on shared code means your security partly depends on links you do not control, so you verify rather than assume.
Check what your site actually serves
You can pin and lock all you like, but the real question is what code ends up running on your live pages. An automated scan reads the scripts your site actually delivers to visitors and flags third-party resources running without integrity checks. Scan your site and see what you are really shipping.