Teardown · 5 min

The supply-chain attack aimed at AI-generated code

Ask an AI for code and it will sometimes import a package that does not exist. Someone noticed the same fake names recur — so they registered them.

Ask an AI to write code and it will occasionally reference a software package that does not exist. It is not lying in any meaningful sense — it has produced a plausible name, because plausible is what it optimises for. The name looks right. It follows the naming conventions of the ecosystem. It is exactly what such a package would be called, if it existed.

Someone noticed that the same non-existent names come up repeatedly. So they registered them.

How the attack works

The chain is short, which is what makes it effective:

A developer asks a model for code. The model's answer imports a package that was never published. The developer runs the install command, because that is what you do when an import fails. If an attacker has registered that name, the install succeeds — and arbitrary code from a stranger now runs with the permissions of whoever ran the command.

That is usually a developer machine with access to source code, credentials and production systems. It is a very good place to end up.

The technique has been named slopsquatting, after typosquatting — the older trick of registering names one keystroke away from popular packages. The difference is that typosquatting waits for a human to make a mistake. This one waits for a machine to make a predictable one.

Why it is worse than it sounds

Hallucinated names are not random. Given similar prompts, models tend to produce similar plausible names, which means an attacker does not have to guess broadly. They can generate candidates the same way the victim will, register the ones that recur, and wait.

And the failure has no symptom. A malicious package can behave exactly like the real thing would have — the code works, the tests pass, the feature ships. The payload runs quietly at install time and nothing about the working application looks wrong afterwards.

Compare that to the failures people worry about. A crash is loud. A leaked key eventually surfaces. This one produces a functioning system with a stranger's code in it.

The defence, which is one line

Verify a package exists and is what it claims before installing it. That is the whole control. In practice it means: check the registry page, check the download counts, check the repository the package points at is real and maintained, and be suspicious of anything published recently with no history.

For a team, make it structural rather than a matter of discipline: a lockfile so the same versions install everywhere, an allowlist or private registry mirror for anything new, and a scan in the pipeline that flags dependencies added in the last commit. None of this is expensive. All of it is boring, which is why it is skipped.

What to ask your developers

Two questions, and they are quick:

How does a new dependency get into our codebase? If the answer is "someone installs it", you have no control. If it is "someone installs it and the review flags it", you have one.

Do we pin versions and commit the lockfile? This decides whether a compromised package that gets pulled later affects you at all.

The wider point

The interesting thing here is not the specific attack. It is the shape: AI made a new, predictable mistake at scale, and someone built a business model on the predictability.

That is going to keep happening, and it is why "we use AI to write code" is a statement about speed, not about safety. Speed is real and worth having. It just does not come with the controls attached — those are a separate decision, and somebody has to make it deliberately. If you are not sure whether anyone has, a Reality Check is a week and a fixed fee to find out.

This is the part we do — the crossing from a demo to a system that survives production.