AI coding agents are making software supply-chain attacks easier to scale—and harder to notice.
You ask your coding agent to “add relative timestamps to the activity feed.” Forty seconds later, it’s done.
The diff looks clean.
The tests pass.
The feed says “3 minutes ago.”
You skim the component, approve the PR, and merge.
You reviewed the code it wrote.
Hopefully.
But did you review the code it installed?
Probably not.
That innocent-looking line in package.json can introduce an entire dependency tree: someone else’s code, their dependencies, and whatever their installation scripts decide to execute on your machine.
And your machine might have your SSH keys, npm tokens, cloud credentials, and access to production.
In 2026, this isn’t theoretical anymore.
Two npm attacks that should change how we review code
March 31: axios — a trusted package turns malicious
Attackers compromised an axios maintainer’s account and published two malicious versions: 1.14.1 and 0.30.4.
The releases introduced a phantom dependency, plain-crypto-js, whose installation script deployed a remote-access trojan targeting Windows, macOS, and Linux. The malicious versions were live for roughly three hours. Plenty of time for automated builds and developer machines to install them.
The publishing workflow had another lesson: axios had adopted OIDC trusted publishing, but a long-lived npm token was still available. When both credentials were present, npm used the token.
The old credential remained a valid way in.
June 17: Mastra — one typo, a huge blast radius
Mastra is a framework for building AI agents.
Attackers compromised its npm organization and introduced easy-day-js, a typosquat of the popular dayjs library. The malicious dependency spread across more than 140 packages, representing over 1.1 million combined weekly downloads.
Its installation script fetched a second-stage payload and then deleted itself.
No suspicious application feature. No obvious malicious function in the code you reviewed. Just another dependency. Both attacks turned dependency installation into the execution point.
You didn’t need to run the application. You didn’t need to import the malicious package.
You only needed to install it.
npm install is code execution.
It just looks like housekeeping.
And then there’s RubyGems
On May 11–12, more than 2,000 malicious gems appeared on RubyGems in two days. The platform temporarily closed new account registrations to contain the campaign.
The gems abused RubyDoc.info’s documentation build process to execute code and attempted to steal developers’ API keys.
Researchers reported that the packages appeared to have been generated by an LLM. Hundreds included “oai” in their names. In a September 12 report, researchers attributed the campaign to a swarm of OpenAI agents. OpenAI disputed the characterization, saying its agents were using RubyGems for benign tasks, and said it would investigate further.
The broader lesson doesn’t depend on who was behind it.
AI can help create malicious packages at scale, while AI coding agents help developers install them at scale. The humans are increasingly the last line of defense—and sometimes we’re not even looking.
Why AI coding agents make this worse
When a developer adds a dependency, there’s usually some friction.
“I need a date library.”
“Let’s use dayjs.”
“Wait, is this the right package?”
Maybe they check the download count. Maybe they recognize the name. Maybe they ask a colleague.
It’s not a security audit, but it’s a useful smell test built from years of ecosystem experience. Your coding agent doesn’t have that instinct. It has a language model, a task, and a terminal.
Three things change:
- Dependencies arrive without hesitation. The human pause between deciding to use a library and installing it disappears.
- AI can hallucinate package names. Attackers can register those names before an AI-generated suggestion reaches your terminal. This is called slopsquatting.
- Your agent has access to your environment. An installation script can potentially access anything available to the process running it—including credentials.
I wrote about this in Your Agents Have Credentials. Nobody Owns Them. .
The short version: we gave agents powerful tools before we figured out who owns their credentials. Now we’re letting them install other people’s code. Meanwhile, the lockfile—the one file that exposes the dependency tree—is often the first thing reviewers collapse.
We review the code the agent wrote.
We don’t review the code the agent invited into our house.
What I’d actually do
This is another layer in the verification stack .
The goal isn’t to manually audit every package. That’s not realistic.
The goal is to make the dangerous path harder and the safe path automatic.
1. Disable dependency install scripts by default
With npm:
npm config set ignore-scripts true
This prevents package lifecycle scripts from running automatically during installation. Explicitly invoked scripts can still execute, and some packages genuinely need build steps. With pnpm 10, dependency lifecycle scripts are blocked by default unless explicitly allowed. Current pnpm versions use allowBuilds to define which packages may run them; older pnpm 10 versions use onlyBuiltDependencies.
This wouldn’t prevent every supply-chain attack, but it would disrupt the installation-time execution path used in the two npm incidents above.
2. Add a dependency cooldown
Why install a package version five minutes after it appears?
pnpm’s minimumReleaseAge lets you require a version to exist for a minimum period before it can be installed.
That gives the ecosystem time to notice suspicious releases. It’s not a guarantee. A malicious package can remain undetected, and a legitimate new release might contain an urgent fix. But a short delay is a useful filter when the alternative is letting an agent install whatever it finds immediately.
3. Let agents propose dependencies. Let humans approve them.
Put the rule in your CLAUDE.md or AGENTS.md:
Do not add, remove, or upgrade dependencies without explaining why the change is needed and requesting human approval.
But don’t stop there.
An instruction file is not a security boundary. Enforce the policy in CI. Require explicit approval for dependency changes, and make the reviewer inspect the package names, versions, and lockfile diff.
The agent can do the research.
The human owns the decision.
4. Sandbox the agent
Run coding agents in a container or development VM with limited access to your host.
Don’t casually mount your entire home directory. Don’t give every agent your SSH keys, npm credentials, and cloud profiles. Use scoped, short-lived credentials when access is necessary, and keep production credentials out of the development environment.
If a malicious installation script runs anyway, the best outcome is that it finds nothing valuable.
5. If you publish packages, remove long-lived tokens
Use trusted publishing where supported.
Then revoke old publishing tokens and audit the remaining credentials. The axios incident is a reminder that security is only as strong as the weakest valid authentication path. OIDC doesn’t neutralize an old token that’s still accepted.
The bottom line
AI made writing code cheap.
It also made pulling in other people’s code cheap.
One prompt. One dependency. Forty seconds.
And somewhere in that process, an agent may have executed code you never reviewed, from a package you never intentionally chose, with credentials you forgot it could access. We need to stop treating dependency installation as a harmless implementation detail.
Review the lockfile like it’s code.
Because it is.
And if your AI coding agent can install a package without anyone noticing, you don’t have an AI productivity problem.
You have a supply-chain security problem.
Discover more from Ido Green
Subscribe to get the latest posts sent to your email.