What is slopsquatting, exactly?
Typosquatting relies on human typos: an attacker registers a name close to a popular one and waits. Slopsquatting relies on machine invention. A language model, asked to write code, produces an import or an install command for a package that sounds right and does not exist.
The term is used for this specific pattern. Researchers studying code-generating models described package hallucination as a form of package confusion attack that threatens the software supply chain, in a 2024 academic paper titled We Have a Package for You. That study measured hallucinations across many models and languages. We are not quoting its rates here, because they vary by model, prompt and setup, and you should read the paper if you need them.
This post does not point to a specific confirmed breach as an example. The risk is mechanical and well described, and the defenses do not depend on any particular incident.
How does the attack work step by step?
- 1An assistant suggests a package name for a task. The name is plausible but unregistered.
- 2An attacker who has seen or predicted that name registers it on the public registry and publishes a package under it.
- 3The package contains something harmful, often code that runs during installation.
- 4A developer who trusts the suggestion runs the install command. The registry resolves the name to the attacker's package.
- 5The install runs on your laptop, your CI server or your deployment pipeline, with whatever access those have.
Why does the registry model allow it?
Public registries such as npm are first come, first served for unscoped names. If a name is free, anyone can publish it. That is exactly what makes the ecosystem open, and it is also why an invented name is a claimable asset.
npm's scope system is the partial counterweight. A scope is a namespace tied to a user or organization, and npm's docs note that it lets you create a package with the same name as another user's without conflict. A scoped name like @yourorg/utils tells you who controls it. An unscoped name tells you only that someone got there first.
Then there is the install itself. When you run npm install, the preinstall, install and postinstall scripts of dependencies can run, after the modules are installed. A malicious package does not need you to import it. Installing it can be enough.
Why are AI-built apps especially exposed?
The habit is the risk. In an agent-driven workflow, the assistant proposes a dependency and immediately runs the install, often with the developer approving commands in bulk. The human review step that would catch an unfamiliar name gets skipped because the flow feels fast and the app works.
A second effect: a dependency that the assistant hallucinated will fail to import in most cases, which prompts a retry. If the retry installs a real package, you may never notice the first attempt reached the registry. The safe assumption is that any install command you did not read is a decision you did not make.
What defenses actually work?
- Verify before installing. Look up the name on the registry, check publisher, publish date, repository link and maintainers. A brand-new package with a generic name from an unknown account and one version is a red flag.
- Install from lockfiles. npm ci installs exactly what package-lock.json specifies and exits with an error if the lockfile and package.json disagree, instead of quietly updating it. Use it in CI and deployment so nothing new appears unreviewed.
- Review dependency diffs. Treat changes to package.json and the lockfile as code changes in pull requests.
- Prefer scoped and known publishers. For internal packages, use your own scope so nobody else can claim the name.
- Control install scripts. The ignore-scripts setting stops npm from running scripts defined in package.json files. Run installs with it where you can, and run scripts explicitly for the few packages that genuinely need them.
- Check provenance. npm provenance links a package to its source code and build instructions. npm's docs are clear that established provenance does not guarantee the package has no malicious code, so treat it as one signal, not a verdict.
- Run npm audit, knowing its limits. It reports known vulnerabilities in the dependencies in your tree. It is not built to tell you that a name was hallucinated and then squatted.
Commands worth adding to your workflow
The first command asks the registry for the package's identity: when it was created, who maintains it and where its source lives. If it fails with a not-found error, the name is free, and installing is impossible today, but registering it is one command away for someone else. Do not register names you have not planned to own.
The npm audit signatures command verifies registry signatures and provenance attestations for what you downloaded. It tells you whether what you fetched was signed as published, not whether the publisher is benign.
npm view <package-name> name version time.created maintainers repository.url
npm install --ignore-scripts <package-name>
npm ci --ignore-scripts
npm audit signaturesA pre-install checklist
- 1Read the exact command the assistant proposes. Do not approve installs in bulk.
- 2Does the package appear in the official docs of the library you are using, or in a tutorial from its maintainers? If not, be skeptical.
- 3Look it up on the registry. Check creation date, download history, publisher, repository and issue tracker.
- 4Does the repository exist, and does its code match the published package?
- 5Is there a well-known package that does the same job? Prefer it.
- 6Inspect install scripts in the package's package.json before running an install.
- 7Install with scripts disabled first, then commit the lockfile change in its own pull request.
- 8In CI, use npm ci so nothing outside the lockfile can enter.
What to tell your assistant
Instructions help, though they are not a control. Ask the assistant to name the official documentation page for any new dependency, to prefer packages already in your lockfile, and to stop and ask before running installs. A reply that cannot cite a source for the package is a signal to check by hand.
The lasting defense is procedural: a human reads new dependencies, CI installs from the lockfile only, and install scripts do not run by default. Those three habits work whether the bad name came from a model, a typo or a tutorial.
Frequently asked questions
What is slopsquatting?
Slopsquatting is an attack where someone registers a package name that AI assistants tend to hallucinate. When a developer runs the assistant's install command, the registry serves the attacker's package. It is like typosquatting, except the trigger is a model inventing a plausible name rather than a human mistyping.
Does npm audit catch hallucinated packages?
Not reliably. It reports known vulnerabilities in dependencies already in your tree. A freshly registered malicious package has no advisory yet, and npm audit is not designed to flag that a name was invented by a model. Verify names manually and use lockfiles.
Does npm provenance make a package safe?
No. Provenance links a package to its source code and build, and it shows where and how it was built. npm's documentation states it does not guarantee the package has no malicious code. Use it as one signal alongside publisher history, repository review and script inspection.
Should I disable npm install scripts?
Running installs with ignore-scripts prevents npm from running lifecycle scripts defined in package.json files, which is a common place for malicious code to execute. Some legitimate packages need scripts to build native modules, so enable those deliberately and explicitly instead of allowing everything.