Blog/Security & compliance

Slopsquatting: when coding agents install packages that do not exist

How LLMs hallucinate package names, how attackers register them, and the registry, lockfile and agent-harness controls that stop the install.

··6 min read

  • Supply chain security
  • Coding agents
  • npm
  • PyPI
  • Package hallucination
A coding agent proposes an install command for a package name that does not exist, and an attacker registers that name before the install runs.

Key takeaways

  • In a 576,000-sample study, at least 5.2% of packages suggested by commercial models and 21.7% by open models did not exist.
  • Hallucinated names repeat, so an attacker can register them in advance and wait for agents and developers to install them.
  • Release-age delays in npm, pnpm and uv block brand-new versions, but not a squatted name that was registered months ago.
  • Make the agent ask before every install, verify unknown packages against the registry, and keep install scripts off by default.
  • Lockfiles with hashes and CI that refuses unreviewed dependency changes turn a silent install into a reviewed diff.

Listen to this article

0:000:00

A coding agent writes import fastjson_validator, runs pip install fastjson-validator, and the install succeeds. Nobody on the team has heard of the package, because it does not exist in any documentation: the model made the name up. What made the install succeed is that someone else noticed the same hallucination earlier and registered the name. That attack has a name now, slopsquatting, and coding agents make it more likely, because they run install commands without a human typing them.

This article covers what the research measured, why hallucinated names are predictable enough to squat, and the controls that work at each layer: the agent harness, the package manager, the lockfile and CI. It builds on sandboxing coding agents, which limits the damage once something malicious does run.

What is slopsquatting?

Typosquatting registers reqeusts and waits for someone to mistype requests. Slopsquatting registers a name that a model invents, such as a plausible but non-existent wrapper or CLI, and waits for models to suggest it. The researchers who first measured it call it a package confusion attack: the victim believes they are installing a real dependency, and the registry happily serves whatever the attacker uploaded, including install scripts that run on the developer's machine or in CI.

How a slopsquatting attack worksAn attacker prompts models, collects hallucinated package names that repeat, and registers them. Later a developer or coding agent receives the same hallucinated name, runs the install, and the malicious package executes its install script.Harvestprompt modelsRegisterrepeated namesSuggestagent writes codeInstallno human checkExecuteinstall script
The attacker's cost is registering names; the defender's chance is any step between suggestion and execution.

How often do models hallucinate packages?

The most thorough study is Spracklen et al., published at USENIX Security 2025. They generated 576,000 code samples with 16 popular code models in Python and JavaScript and checked every referenced package against the registries.

FindingValue
Hallucinated packages, commercial models (average, at least)5.2%
Hallucinated packages, open-source models (average, at least)21.7%
Unique hallucinated package names205,474
Code samples analyzed576,000

The number that matters for attackers is not the rate but the repetition: hallucinations are not random noise, the same prompts produce the same invented names again, and that makes them worth registering. The authors also tested mitigations such as retrieval and self-checking and report that these significantly reduce hallucinated packages while keeping code quality, which is useful, but does not remove the need for checks outside the model.

Has it happened outside the lab?

In March 2024, Bar Lanyado of Lasso Security noticed models recommending a Python package called huggingface-cli, which did not exist; the real CLI ships with the huggingface_hub package. He uploaded an empty package under that name, used a second dummy package to separate scanner traffic, and counted more than 30,000 authentic downloads in three months. Installation instructions for the fake package had made it into the README of a research repository from Alibaba. The package was harmless; the next one might not be.

What should the agent harness enforce?

The cheapest control is at the moment of the install. A human typing npm install usually knows why; an agent running it in the middle of a task does not stop to wonder. Configure the harness so that installs need approval, and give the agent a quick way to check a package before it proposes one. I describe the general idea of guides and sensors in harness engineering.

// .claude/settings.json: installs always ask, the lockfile is never edited by hand
{
  "permissions": {
    "ask": [
      "Bash(npm install:*)", "Bash(npm i:*)", "Bash(pnpm add:*)", "Bash(yarn add:*)",
      "Bash(pip install:*)", "Bash(uv add:*)", "Bash(uv pip install:*)", "Bash(npx:*)"
    ],
    "deny": ["Edit(package-lock.json)", "Edit(pnpm-lock.yaml)", "Edit(uv.lock)"]
  }
}
  • Verify before proposing: a package must exist, have a source repository, a history of releases and real usage. A name with one release from last week deserves a closer look regardless of how confident the model sounds.
  • Prefer the standard library and existing dependencies. An instruction in AGENTS.md to reuse what the project already depends on reduces new names at the source.
  • Run the agent in a sandbox without credentials, so a malicious install script finds nothing worth stealing, as covered in coding agents and secrets.

Which package manager settings help?

ToolSettingEffect
npmmin-release-age, beforeOnly install versions older than N days, or published before a date
npmignore-scripts, allowScriptsDo not run install scripts, or only for listed packages
pnpmminimumReleaseAgeMinimum minutes since publication, including transitive dependencies; 1440 by default since pnpm 11
uvexclude-newerIgnore files uploaded after a timestamp or within a duration such as 7 days
pip / uv--require-hashesEvery requirement pinned and verified against a hash

Be clear about what release-age settings do. They filter on when a version was published, which protects against brand-new registrations and against compromised releases that are usually pulled within hours. pnpm's documentation notes that most malicious releases are discovered and removed within an hour. A hallucinated name an attacker registered six months ago is old enough to pass. Combine the delay with install approval and a check on how long the package itself has existed.

# .npmrc
min-release-age=7
ignore-scripts=true

# pnpm-workspace.yaml
minimumReleaseAge: 10080   # 7 days, in minutes

# pyproject.toml
[tool.uv]
exclude-newer = "7 days"

What should CI check?

CI is where an agent's silent change becomes a reviewed diff. Install with npm ci, pnpm install --frozen-lockfile or uv sync --locked, so the build fails when the manifest and lockfile disagree. Then make new dependencies visible: a job that lists packages added since the base branch, with their first publication date and repository URL, and requires a named reviewer when the list is not empty. That review is where never heard of it turns into a question instead of a merge.

What is the short checklist?

  1. Install commands require approval in every agent harness the team uses.
  2. Agents run in a sandbox without production credentials or long-lived tokens.
  3. Install scripts are off by default, with an explicit allowlist.
  4. A release-age delay is set in npm, pnpm or uv.
  5. CI installs from the lockfile only and flags every new dependency for a named reviewer.

Sources

  1. Spracklen et al.: We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs (2024)
  2. Lasso Security, Bar Lanyado: Diving Deeper into AI Package Hallucinations (Mar 2024)
  3. npm Docs: config (min-release-age, before, ignore-scripts, allow-scripts)
  4. pnpm: Dependency resolution settings (minimumReleaseAge)
  5. uv: Settings reference (exclude-newer, require-hashes)
  6. pip documentation: Secure installs and hash-checking mode

Frequently asked questions

What is slopsquatting?

Slopsquatting is registering a package name that LLMs tend to hallucinate, so that code or install commands generated by a model pull in the attacker's package. It is a variant of typosquatting, except that the wrong name comes from the model rather than from a typo.

How often do LLMs hallucinate package names?

Spracklen et al. generated 576,000 code samples with 16 models in Python and JavaScript and found that at least 5.2% of suggested packages from commercial models and 21.7% from open-source models did not exist, with 205,474 unique hallucinated names.

Has this happened in practice?

Yes, as a test. In 2024 Lasso Security researcher Bar Lanyado found models recommending a non-existent Python package called huggingface-cli, uploaded an empty package under that name, and recorded more than 30,000 authentic downloads in three months. Installation instructions for it had appeared in a repository from Alibaba.

Does a minimum release age protect against slopsquatting?

Only partly. Settings such as npm min-release-age, pnpm minimumReleaseAge and uv exclude-newer block versions published very recently, which helps against freshly registered names and compromised releases. A name an attacker registered months ago passes the check.

What should I configure for coding agents?

Require approval for every package install command, run agents in a sandbox without access to secrets, disable install scripts by default, and fail CI on dependency changes that nobody reviewed. Let the agent check a package on the registry before it proposes it.

Sounds like what you need?

Tell me about your project or role – I’d love to hear from you.