For years, the cardinal rule of security was just "patch your stuff."
Got a CVE alert? Update. Patch Tuesday? Apply it. CI/CD pipeline? Hook it up to pull the latest minor versions automatically. The logic made perfect sense: dragging your feet on updates was what got you hacked.
Then SolarWinds happened in 2020.
Nation-state hackers didn't bother storming the front doors of the Pentagon or the US Treasury. They just slipped malware into standard software updates from a trusted vendor. When organizations dutifully downloaded those updates, they essentially held the door open for the attackers to walk right in.
SolarWinds proved a terrifying point: the update mechanism itself can be a weapon.
If you look at what happened on March 31 of this year, it's pretty obvious we haven't recovered from that shift in reality. Over a single 24-hour stretch, two separate incidents—one an attack, one a complete blunder—showed just how messy the modern software supply chain really is.
The Inbound Threat: Axios gets hijacked
Take axios. It has over 100 million weekly downloads. It's the default way to make HTTP requests in JavaScript. If you're building for the web, it's probably running in your stack right now.
Late on March 31, someone hacked into a lead maintainer's NPM account and published two malicious updates (1.14.1 and 0.30.4).
The attackers were smart about it. They didn't stick the malware directly into the main Axios codebase. They hid it in a nested dependency called plain-crypto-js. If you ran an npm install, that sub-dependency fired off a postinstall script and quietly dropped a Remote Access Trojan (RAT) onto your machine.
This is the exact nightmare scenario. Following "best practices" is what got people compromised. Any developer whose package.json was set to auto-pull the latest minor version ^1.14.0, or any automated pipeline that built a release during that window, pulled down the malware.
If that happened to your machine, the advice isn't to run a virus scan. It's to throw the machine out, wipe it entirely, and assume every SSH key, database password, and AWS token sitting on it is gone forever.
The Outbound Blunder: Claude Code leaks itself
While the Axios hack was a calculated attack on what we pull in, Anthropic had an embarrassing disaster with what they pushed out.
Anthropic recently launched Claude Code, their highly anticipated AI CLI tool. But on the same day the Axios hack unfolded, a developer made a packing mistake on NPM. They accidentally bundled a massive 60-megabyte debugging file into the public release.
That cli.js.map file contained a hardcoded URL pointing to an open, unauthenticated internal bucket. Suddenly, the entire internet could download 512,000 lines of proprietary, unobfuscated TypeScript. The core logic of a multi-billion dollar AI company was floating around GitHub in minutes.
This wasn't a sophisticated hack. It was just a typo in a build config.
Our modern Javascript toolchains—Webpack, Rollup, endless TS compilers—are so tangled that even elite engineering teams can accidentally ship their crown jewels to the public registry.
Why SBOMs aren't fixing this
After SolarWinds, the industry's default answer to all of this became the Software Bill of Materials (SBOM). The idea is that if you have an exact ingredient list of your software, you can secure it.
It sounds great in board meetings, but practically, it misses the point.
An SBOM is static. It might tell you that your app relies on Axios. But it doesn't tell you if the maintainer's laptop was compromised three hours ago. It won't stop a postinstall script from executing a RAT during the build phase—long before your security scanner ever gets to read the updated SBOM.
An ingredient list doesn't help much if the chef is the one poisoning the food.
The Unsolvable Problem
We're stuck in a weird spot.
If we don't apply updates, we get hit by automated botnets scanning for old, patched vulnerabilities. But if we automate our updates, we expose our build servers to poisoned supply chains.
If we pin all our dependencies to exact versions, the codebase turns into legacy tech debt faster than we can manage. Use floating versions instead? You're one compromised open-source maintainer away from a massive breach.
There are ways to fight back. We can isolate our CI/CD pipelines in air-gapped containers. We can use --ignore-scripts to stop NPM packages from running arbitrary code on install.
But the real takeaway from March 31 is that blind trust is dead. You can't assume a package is safe just because it's popular or signed by a big vendor. You have to design your systems assuming the build server will eventually pull down something malicious—and make sure the rest of your infrastructure doesn't go down with it.
P.S. Project Update: ThunderSweep
I took about a week and a half off for some intensive training. As expected with Indie Hacking, the moment you stop marketing, the traction stops too. Active users slipped from 7 down to 4. I'm getting back into the swing of things this week. A big thanks to the 4 of you still running your local scans! Momentum is everything, so we’re pushing forward this week.