Browse the blog
Sentrint Blog
AI-built apps · Vulnerabilities

Your AI invented a package name. Someone else registered it

When an AI coding tool invents a package name that does not exist, an attacker can register that name and wait. Nearly one in five AI-generated code samples in one study referenced a package that was never real. Agents install these without a human ever typing the name.

In January 2026, a security researcher at Aikido noticed something odd on npm. A package called react-codeshift was being requested hundreds of times a day.

It had never existed. A language model had invented the name by blending two real tools, jscodeshift and react-codemod. The invented name got written into a batch of AI agent instruction files. Those files were shared, forked, and copied into 237 repositories. From then on, coding agents in all of those projects dutifully tried to install a package nobody had ever written.

Nobody typed that name and no human ever chose it. It propagated because agents read instructions written by other agents, and none of them stopped to ask whether the thing they were installing was real. This is called slopsquatting, and it is a genuinely new shape of supply chain attack.

How does slopsquatting work?

The attack has three steps, and only the first one is unusual. The other two are the ordinary behaviour of a package manager doing its job.

An LLM hallucinates a dependency. Ask for a feature, get code that imports react-codeshift. The name is plausible because it is built from the parts of real names. It looks right in a diff.

An attacker registers that name. Hallucinations are not random. Models make the same fabricated name repeatedly, because they are blending the same real names the same way. So an attacker can collect the common ones and publish packages under them, in advance, and wait.

Your install command does the rest. npm install does not distinguish between a package you chose and a package your assistant invented. If the name resolves, it installs, and an npm postinstall script runs whatever the author wrote on your machine.

The Cloud Security Alliance documented the scale in a research note this year. In the sample they analysed, 440,445 code samples (19.7%) referenced at least one package that did not exist, across 205,474 unique fabricated names. That is a very large surface for an attacker who only needs to guess correctly once.

Why is this worse with agents than with people?

Because a person pauses and an agent does not. The whole attack depends on that gap.

When you copy a snippet off Stack Overflow and it wants an unfamiliar package, you usually look it up. You notice it has 12 weekly downloads, no repository link, and was published last Tuesday. You do not install it.

An agent with permission to run shell commands has no such reflex. It reads its own instruction file, sees npx react-codeshift, and runs it. The failure mode of an agent is to try harder, not to stop.

That is what made react-codeshift spread. It was not in anybody's package.json. It was in agent skill files, which are shared and forked like any other config, and each fork carried the phantom dependency with it.

Researchers have started calling the wider pattern HalluSquatting, because the same trick works on domains and repository names, not just npm packages. The common ingredient is an agent fetching and executing a name before anyone has checked the name is real.

How do I check my own project?

Four checks. The first two take a minute.

1. Look for packages that do not exist upstream. For each dependency, ask npm directly:

npm view <package-name> versions

A 404 on something your code imports is the whole finding. There is nothing further to investigate: the package does not exist, so whatever resolved at install time was not what the code intended.

2. Look at what your agent was told to install. This is the step people skip, because it is not in package.json. Search your instruction files:

grep -rn "npx \|npm install \|pip install " \
  CLAUDE.md AGENTS.md .cursorrules .windsurfrules .claude/ .cursor/ 2>/dev/null

Anything named there gets installed without review. If you copied a skill or rules file from someone else's repository, you inherited their hallucinations too.

3. Age and provenance on anything unfamiliar. A real dependency has history. A slopsquatted one usually does not:

npm view <package-name> time.created repository maintainers

Published in the last month, one version, no repository link, no maintainers you recognise: treat that combination as hostile until proven otherwise. Any one of those signals alone is unremarkable, and all four together almost never describe a package you actually meant to install.

4. Check for install hooks. The payload almost always runs from a lifecycle script:

npm view <package-name> scripts

A preinstall, install or postinstall hook on a package that claims to be a code transform is a red flag by itself. Those hooks are where the payload runs, and a legitimate utility of that kind rarely needs one.

Why doesn't my scanner catch this?

Because most dependency scanners answer a different question from the one you think you are asking them. They are very good at the question they do answer.

A vulnerability scanner compares your dependencies against a database of known bad versions of known real packages. react-codeshift was not in that database, because until an attacker registered it, it was not a package at all. There was no CVE to match. There was nothing to match.

That is the gap. The tooling is built to find a flawed version of something legitimate, and slopsquatting ships something illegitimate that has no history to be flawed in the first place.

The CSA note makes the same point about unused-imports, a hallucinated stand-in for the real eslint-plugin-unused-imports. It kept pulling hundreds of weekly downloads even after npm had flagged it, because the agents installing it were not reading npm's warnings.

What actually prevents it?

One habit and one rule, and the habit is worth more than the rule. Neither takes long.

Verify the name before you install it. Not the code, the name. Does the package exist, how old is it, does it link to a repository, does the repository have the history you would expect. Thirty seconds per new dependency.

Put it in your rules file. Every AI coding tool reads standing instructions from a file, and this is exactly the kind of constraint that belongs in one:

Before adding any dependency, verify the package exists on the registry, has more than one published version, links to a public repository, and has no install lifecycle scripts. If any check fails, stop and tell me rather than installing it.

That sentence costs nothing and it turns an agent's default behaviour from install-and-see into check-first. The full guide to rules files is here.

Lock your dependencies and commit the lockfile. A lockfile pins resolved versions, so a name that resolved yesterday cannot silently resolve to something else tomorrow.

Where this sits in your risk

Honestly? Below the boring ones.

If your Supabase tables have RLS off, or your API key is in your frontend bundle, fix those first. They are more common, they are already exploitable, and bots are already scanning for them. The six-check list covers those.

Slopsquatting matters because it is growing, because agents amplify it in a way nothing else in your stack does, and because it is invisible to the tools most people assume are watching. It is the one on this blog most likely to be new to you.

Sentrint reads your whole repository, including what your dependency manifests actually pull in, and reports it in plain English with a fix you can paste back into the tool that built the app. A code scan, not a pentest, and the first one is free with no card.

Run npm view on anything you do not recognise today, though. That one is free and immediate.


Sources: the react-codeshift case was found by Charlie Eriksen at Aikido Security in January 2026. The hallucination-rate figures come from the Cloud Security Alliance research note on slopsquatting and the AI supply chain.

More on AI-built apps
Enough reading. See your own findings.
A free scan turns this into a list of what to fix, in order.
Run your free scan