Two npm security events. Same day. Same registry. Different failure modes. Same lesson.
Attack: axios
axios gets downloaded over 100 million times a week. On March 31, an attacker hijacked the npm credentials of a lead maintainer, changed the account email to an anonymous ProtonMail address, and published two poisoned versions: 1.14.1 and 0.30.4.
The attack was sophisticated. Neither version contains malicious code inside axios itself. Instead, they inject a fake dependency called plain-crypto-js that drops a remote access trojan on your machine. Three separate payloads, pre-built for macOS, Windows, and Linux. Both release branches hit within 39 minutes. Every trace was designed to self-destruct after execution.
The tell: there’s no tag in the axios GitHub repo for 1.14.1. It was published outside the normal release process entirely. CI/CD was bypassed completely.
— Feross Aboukhadijeh (@feross), Socket SecurityCRITICAL: Active supply chain attack on axios - one of npm’s most depended-on packages.
StepSecurity called it one of the most operationally sophisticated supply chain attacks ever against a top 10 npm package.
Accident: Claude Code
Hours later, a different kind of leak. Chaofan Shou discovered that Anthropic shipped a source map file in the @anthropic-ai/claude-code npm package (v2.1.88), exposing the full Claude Code source code. Not a build artifact someone forgot to gitignore. A .map file that npm’s registry happily served to anyone who looked.
No malicious intent. No attacker. Just a build pipeline that didn’t strip debug artifacts before publishing to the registry. The company building the most popular AI coding tool leaked its own internals through the same package registry that was being actively exploited hours earlier.
The leak was substantial: 1,902 TypeScript source files, internal feature flags for unreleased capabilities, model codenames, and even an “undercover mode” designed to prevent Claude Code from revealing Anthropic-internal information when employees use it on public repos. A 59.8 MB source map, freely downloadable from the npm registry.
axios failed because npm is too trusting: stolen credentials can publish arbitrary code with no verification. Claude Code failed because npm is too transparent: build artifacts that should never ship get served to anyone who asks. The registry’s security model has gaps in both directions.
The Pattern
If this feels familiar, it should. Six days ago, litellm was compromised through a nearly identical attack chain. A threat actor stole CI/CD credentials via a compromised Trivy scanner, then used those credentials to publish backdoored versions to PyPI. The payload harvested SSH keys, cloud credentials, Kubernetes secrets, and crypto wallets from 97 million monthly downloads. It was caught by accident because the attacker’s own malware had a bug.
The mechanic is the same every time: the pipeline has a gap, and something leaks through it. Sometimes it’s malicious code injected by an attacker. Sometimes it’s source code leaked by the maintainer. The direction doesn’t matter. The gap does.
Yesterday I wrote that your architecture is your pipeline. These incidents prove the negative case. When the pipeline has holes:
- axios: No CI/CD gate between “someone with credentials” and “published package.” The poisoned versions were published directly to npm, bypassing the GitHub release flow entirely. A pipeline that required GitHub Actions to publish would have caught this.
- Claude Code: No build step to strip source maps before publish. A pipeline with a post-build verification hook would have caught this.
- litellm: A security scanner in the pipeline was itself compromised, and the pipeline’s own credentials were extracted from runner memory. A pipeline with credential isolation would have limited the blast radius.
Three incidents in six days. All pipeline failures. None of them would have been prevented by better code architecture, cleaner abstractions, or more sophisticated design patterns. All of them would have been prevented by better pipeline hygiene.
The Vibe Coding Angle
The axios thread ends with “this is the wake up call all vibe coding bros need to hear right now.” That framing is wrong. This isn’t a vibe coding problem. Axios has been around since 2014. Supply chain attacks predate AI coding by a decade.
But there is a real intersection. AI agents run npm install and pip install constantly. They pull dependencies without the human pause of “do I trust this package?” They don’t check GitHub tags against npm versions. They don’t notice when a new transitive dependency appears that didn’t exist yesterday.
The guardrails we’ve been writing about aren’t just about preventing agents from writing bad code. They’re about preventing agents from pulling bad code. --ignore-scripts in CI. Lockfile pinning. Dependency scanning. These aren’t nice-to-haves anymore. They’re the difference between a routine npm install and a remote access trojan.
If you installed axios@1.14.1 or axios@0.30.4, assume compromise. Pin to axios@1.14.0 or axios@0.30.3. Rotate all secrets, API keys, SSH keys, and credentials on affected machines. Check network logs for C2 connections. Add --ignore-scripts to CI npm installs going forward.
One Lesson
100 million weekly downloads and one compromised maintainer account. That’s all it took for axios.
One missing build step and a .map file. That’s all it took for Claude Code.
The dependency graph is load-bearing infrastructure, and we keep treating it like a convenience feature. Every npm install is a trust decision. Every pip install is a trust decision. Every build pipeline that publishes to a registry without verification is a trust decision.
The pipeline is the architecture. When it has gaps, things leak through. Both directions.


