Skip to content

+ Intertrace Threat ResearchTLP:CLEAR7 sources

Threat research9 min read

Slopsquatting: the install is the attack, not the hallucination

Code-generating models invent package names and repeat many of them, and coding agents install what they invent. What the research measured, why better models and code review are not controls, and the registry and gateway checks that break the chain.

How attacks on AI agents work in practice, from public incidents and our own test corpora, and the controls that stop them.

October 18, 2026 · 9 min read

Supply ChainCoding AgentsPackage HallucinationSlopsquatting
Contents
  1. 01The evidence: a predictable supply of names, and agents as the demand
  2. 02Why the install, not the import, is where code runs
  3. 03Objection one: a better model will make this go away
  4. 04Objection two: code review will catch an unfamiliar dependency
  5. 05Objection three: we can claim or blocklist the bad names
  6. 06What breaks the chain
  7. 07What Intertrace reads in an install
  8. 08Run this from a CI runner this week

Spracklen and colleagues checked about 2.23 million package recommendations from 16 code-generating models against the PyPI and npm name lists. Of those, 440,445 named packages that did not exist [1]. When they re-ran each of 500 prompts that had produced a hallucination ten times, the same invented name came back in every run 43% of the time [1].

Typosquatting needs a person to mistype a real name. Package hallucination removes the person: the model produces a plausible name with confidence, the name resolves to nothing, and that empty space in a public registry belongs to whoever claims it first. Andrew Nesbitt described slopsquatting as an LLM hallucinating a non-existent package name and a bad actor registering it maliciously, crediting Seth Larson with the name in April 2025 [3].

Our claim is that teams look for the fix in the wrong place. The model's suggestion is harmless text. The consequential action is the install, and that is where the control belongs: a registry you operate, an age and popularity gate, and an install that asks first. Below are the evidence and the three objections we hear most.

The evidence: a predictable supply of names, and agents as the demand

A hallucination becomes an attack surface when three things hold. The name is unregistered when the model first invents it. It recurs, so registering it pays off across many victims. And something installs it without checking. The research measured the first two; coding agents supply the third.

The study tested three commercial GPT models and 13 open-source variants on Python and JavaScript prompts drawn from Stack Overflow questions and package descriptions, producing 576,000 code samples checked against registry lists taken on January 10, 2024 [1]. The 440,445 invented recommendations, 19.7% of the total, covered 205,474 unique names. In the repeat test, 58% of names reappeared more than once and 39% never did [1]. An attacker does not need to predict a random error. They run popular prompts, collect the names that keep coming back, and register those.

Package hallucination rates by model typeFig. 1
AVERAGE SHARE OF RECOMMENDED PACKAGES THAT DON'T EXISTOpen-source models21.7%Commercial models5.2%0%5%10%15%20%25%205,474unique hallucinated package names576,000code samples across two programming languages

On average, 5.2% of the packages commercial models recommended did not exist, against 21.7% for open-source models, across 576,000 code samples in two programming languages that produced 205,474 unique hallucinated package names (Spracklen et al., USENIX Security 2025).

Selected findings from Spracklen et al. and what each means for a defender [1]
FindingReported figureDefensive reading
Overall hallucinated share440,445 of about 2.23 million recommended packages (19.7%)Invented names are a routine output, not a rare failure, so the control must sit at install time.
Commercial vs open-source averageAt least 5.2% vs 21.7%Model choice changes the rate but never removes it; do not treat a better model as a control.
Unique invented names205,474Too many to pre-register defensively; an allowlist of known names scales better than a blocklist of bad ones.
Repeat behavior on re-query43% in all 10 runs, 58% more than once, 39% neverRecurring names are predictable targets, which is what makes registration worthwhile for an attacker.
Distance from a real name48.6% at Levenshtein distance 6 or moreMost invented names are not near-misses of real ones, so typosquat similarity checks will miss them.
Cross-ecosystem confusion8.7% of hallucinated Python names were valid npm packagesA name that is real in one registry can be fake in another; check the ecosystem, not just the string.
Self-detectionThree of four tested models detected their own hallucinations with accuracy above 75%Asking the model to double-check helps, but it is advice to the model, not enforcement.

Two caveats keep these numbers honest. The models came from a January 2024 leaderboard, and today's will have different rates, which we do not know and will not guess. And the study measured recommendations, not installs or attacks. What it established is the precondition an attacker needs.

People do install them

Bar Lanyado of Lasso Security tested whether hallucinated names get installed [2]. Models repeatedly suggested a Python package called huggingface-cli, which matches the name of Hugging Face's command-line tool but not the package that provides it. He published an empty package under that name, plus an unrelated dummy package to estimate how many downloads came from automated scanners, and reported more than 30,000 authentic downloads in about three months. He also found the name in installation instructions in a research repository README belonging to Alibaba [2]. The package did nothing, so the harm was zero. The point is that a model error had already escaped the chat window into documentation, where people and agents would copy it again.

Why the install, not the import, is where code runs

In a chat interface a person sits between the suggestion and the install and might notice an unfamiliar name. A coding agent with a terminal tool removes that pause. It writes the import, runs the test, sees ModuleNotFoundError and runs pip install, often in the same turn and often without showing the name to anyone.

From hallucinated name to code executionFig. 2
Model suggestsa name that doesn't existAgent runs installpip / npmPublic registrythe name resolvesAttacker packagepre-registeredCode executesinstall hooksINSTALL ASKS FIRSTALLOWLISTED REGISTRYAGE + POPULARITY GATEbreaking any one link stops the attack · the install step is the cheapest place to ask

Five steps connect a model's invented name to code running on your machine. Three checkpoints (an allowlisted registry, an age and popularity gate, and an install that asks first) each break the chain on their own.

Installation is itself code execution. pip's documentation says installing from distributions involves running arbitrary code unless you restrict it, and recommends hash checking and binary-only installs as countermeasures [5]. npm runs a package's preinstall, install and postinstall scripts during npm install [7]. An attacker who registers a hallucinated name does not need you to import anything. The install alone runs their code with the agent's privileges, and an agent in a developer's checkout can usually read environment variables, cloud credentials in the home directory, SSH keys and repository tokens, while one in CI can often read deployment secrets.

Objection one: a better model will make this go away

Model choice changes the rate and never removes it. Commercial models averaged at least 5.2% invented packages, open-source models 21.7%, and the best result, GPT-4 Turbo, was still 3.59% [1]. A few percent sounds small until you multiply it by the dependency suggestions an organization's agents make in a week. Three of four tested models could detect their own hallucinations with accuracy above 75% [1], which makes asking the model to double-check worthwhile. It is still advice to the model, not enforcement.

Objection two: code review will catch an unfamiliar dependency

Review happens after the install. Picture an illustrative team whose overnight coding agent writes a PDF invoice parser that imports invoicetable-parse, a name we invented for this example, and runs pip install when the test fails on the missing module. Suppose an attacker registered that name two weeks earlier as a source distribution, so pip builds it locally and its setup code sends the CI runner's cloud deployment key to a remote host, while a real PDF library vendored underneath makes the parser work. In the morning the reviewer sees one new line in the requirements file, reasonable code and passing tests.

The theft happened during the build, hours before any person looked. Reviewing the agent's output cannot catch an action that completed mid-session.

Objection three: we can claim or blocklist the bad names

With 205,474 unique invented names in one study [1], you cannot pre-register them all, and registries discourage squatting. Nearly half sit far from any real name, so typosquat similarity checks miss them, and some are real packages in a different ecosystem, so the check has to know which registry it is installing from (see the table). Allowlisting known names scales. Blocklisting invented ones does not.

What breaks the chain

Each checkpoint in the figure stops the overnight install on its own. If the CI runner resolves packages only through an internal proxy that mirrors approved names, the install fails with not-found and the agent has to ask for the dependency. A package published two weeks ago with almost no download history fails a minimum-age rule. And if the agent's role treats installs in CI as actions that ask, a person sees the name invoicetable-parse and declines it.

  • Make public registries unreachable from where agents run and resolve through a proxy you operate. One that passes through but logs every miss and first-time name still gives you the signal.
  • Commit lockfiles and install from them. pip's hash-checking mode (--require-hashes) refuses any artifact whose hash is not already recorded, so an agent cannot add a package without changing a reviewed file [5].
  • Prefer binary-only installs (pip's --only-binary) where your dependency set allows, so source-distribution build scripts never run; a malicious wheel would still install [5].
  • Set a minimum release age. pnpm added minimumReleaseAge in v10.16.0, measured in minutes, with a per-package exclusion list for internal packages you trust [6].
  • Check first-time dependencies for download history, a linked source repository, maintainer age, and whether the name is real in the ecosystem you are installing into.
  • Disable dependency lifecycle scripts by default and allow them for named packages that need native builds [7].
  • Check new dependencies against the OpenSSF Malicious Packages database, which publishes reports of malicious packages from open-source registries in OSV format [4]. It catches known-bad packages, not a name registered yesterday.

Registry controls only work where you configured the infrastructure, and many agents run on laptops with their own package manager settings. A control at the point where the agent asks its tools to act covers both. The unit is the action, not the tool name: run_command might be ls or pip install. A gateway that normalizes shell commands reads the argument, splits commands joined with && or semicolons, looks inside command substitutions and recognizes piped downloads such as curl | sh. Policy can then let a lockfile install in development run and make one that adds a package, or any install in CI or production, ask a one-line question no pull request reviewer would ever see.

The trail a slopsquat leaves

The strongest single signal is a name that failed to resolve in your proxy logs and later resolved, because that is the moment someone registered it. Softer signals worth correlating: agent-issued installs for packages in no lockfile in your organization; first-time dependencies younger than your age threshold or with no linked repository; a Python name that exists on npm but not PyPI, or the reverse; build steps connecting to hosts that are not registries or your artifact store; and repeated not-found errors for the same invented name across teams, which means a model is converging on it. None proves an attack. All of them require installs to leave structured records with the agent, session and package name attached.

What Intertrace reads in an install

Intertrace's enforcer normalizes shell tool calls from their arguments, so a pip install or npm install inside a compound command, a substitution or a piped download is read as what it is, and normalization only ever raises the consequence tier. Agent roles decide whether installs run, ask in production or always ask, with the package name and session in one approval inbox. MCP servers launched through npx or uvx have their launch packages checked against OSV, including the OpenSSF malicious-packages feed. Registry proxies, lockfiles and age gates remain controls you run in your own toolchain.

Run this from a CI runner this week

Invent a library name, confirm it is unregistered, and ask a sandboxed agent session on a CI runner for code that needs it. Then wrap a package install behind && in a test command and try again. The fix is verified when both produce a visible question or a clean not-found from your proxy, never a silent download, and when you can name the agent session that asked. Repeat after every agent framework upgrade, since a new version can change how the terminal tool is invoked.

Sources

Reporting, research and specifications this piece draws on. Links go to third-party sources; analysis and recommendations are Intertrace’s own.

  1. 01We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs (arXiv 2406.10279, USENIX Security 2025) · Spracklen et al., arXiv
  2. 02Diving Deeper into AI Package Hallucinations · Lasso Security
  3. 03Quoting Andrew Nesbitt on slopsquatting (April 12, 2025) · Simon Willison's Weblog
  4. 04OpenSSF Malicious Packages · OpenSSF
  5. 05Secure installs · pip documentation (PyPA)
  6. 06Dependency resolution settings: minimumReleaseAge · pnpm
  7. 07npm scripts: lifecycle scripts · npm Docs

About this desk

Intertrace Threat Research

Threat research

How attacks on AI agents work in practice, from public incidents and our own test corpora, and the controls that stop them.

All 18 pieces by Intertrace Threat Research

Dated October 18, 2026 · added to intertrace.ai October 19, 2026

+ Runtime enforcement

See these controls on your own agent traffic.

Intertrace sits inline between your agents and the models, tools and MCP servers they call, and decides every call before it runs.

Keep reading

All insights →