Slopsquatting: The 2025 Supply-Chain Attack

JetThoughts cover for Slopsquatting: Supply-Chain Attack on Vibe Coding - a red npm-install card with a fake package suggested by AI, and chips reading 200+ hallucinated packages, $34K MVP cost, CI safelist gate.

Going further (AI in production) · Step 3 of 3 · From Idea to First Paying Customer

Input: any product touching AI in build (which is most products in 2026)

Output: a one-paragraph contract clause + a CI gate that blocks hallucinated dependencies before merge

Supplementary content. This chapter is relevant after you’ve shipped (Module 4+) and your product touches AI in production. Bookmark and return when needed.

In March 2025, Lasso Security published findings that AI assistants suggested over 200 package names across Rubygems, PyPI, and npm that did not exist. Attackers registered those names and waited. By the time the Infosecurity Magazine writeup named the technique “slopsquatting” in April 2025, security teams had already logged the first installs of the proof-of-concept packages on real production systems. You paid $34K for an MVP. The most expensive line in the codebase was free. It was the one a model invented and a developer typed into a Gemfile without checking that the gem existed.

A hand-drawn diagram of the slopsquatting attack chain in five steps: AI hallucinates a package name, attacker watches public prompt logs, attacker registers the name on Rubygems / PyPI / npm with a malicious payload, developer installs without review, damage runs in production. Annotated with the Lasso Security 11-day reproduction window.

What slopsquatting is

LLMs invent package names that sound plausible but do not exist. The original Lasso Security research from March 2025 tested GPT-4, Claude, and the open-source Code Llama against thousands of common developer prompts. About 5.2% of GPT-4’s package suggestions and 21.7% of Code Llama’s were hallucinated. Snyk’s slopsquatting write-up cites follow-up research putting the overall rate at roughly one in five AI-suggested packages across models. Attackers then register the most-suggested hallucinated names as squatted packages, sometimes with a malicious payload (data exfiltration, credential theft, persistence backdoor), sometimes empty until a real victim shows up. Rubygems, PyPI, npm, Composer, and crates.io all have the same exposure. The attack does not need a 0day (a secret, unpatched vulnerability) - just a developer who trusts a model without checking.

A hand-drawn comparison table across three stacks - Rails/Ruby, Django/Python, and Laravel/npm. Each row shows the plausible-sounding package name an AI model hallucinated (active_support_extras_helper, requestz, react-toastify-fork) next to the real package it was confused with (active_record_extra, requests, react-toastify). All three hallucinated names were registered by Lasso researchers as proof-of-concept in April 2025.

The 20-line CI gate (the simplest defense)

A CI gate that fails the build on any new dependency until a human signs off. Every Rails, Django, and Laravel founder can install this in 15 minutes.

What this 20-line CI gate actually does: blocks any pull request that adds a new package until you’ve eyeballed it - cheap protection against the slopsquatting attack pattern above.


# .github/workflows/dependency-gate.yml

name: Dependency Gate

on: [pull_request]

jobs:

  check-new-deps:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - name: Block new dependencies until reviewed
        run: |
          git diff origin/${{ github.base_ref }}...HEAD -- \
            Gemfile.lock package-lock.json requirements.txt composer.lock \
            | grep -E '^\+' | grep -vE '^\+\+\+' \
            | grep -E '(^\+    [a-z]|^\+"[a-z])' && \
            { echo "::error::New dependency added. Tag @founder + sec reviewer for allowlist sign-off."; exit 1; } || \
            echo "No new dependencies. Safe to merge."

That is the entire defense. The PR cannot merge until a human looks at the new gem, the new pip package, or the new npm module and confirms it exists, is maintained, has the download count it should, and matches the name a developer would actually write. The gate runs on every PR. It blocks every new dependency by default. To override: the founder manually approves the new dependency during PR review, confirming the package exists, is maintained, and has the expected download count.

%%{init: {'theme':'base', 'themeVariables': {'fontFamily':'Caveat, Patrick Hand, Comic Sans MS, cursive', 'primaryColor':'#fff5f5', 'primaryBorderColor':'#cc342d', 'lineColor':'#1a1a1a', 'primaryTextColor':'#1a1a1a'}}}%% flowchart TD PR(["PR opened"]) Gate{"New dependency in lockfile?"} Pass["Merge as normal"] Block["Build fails - PR blocked"] Review{"Reviewer checks package"} Allowlist["Add dep-approved label"] Walk["Revert to real package"] PR --> Gate Gate -- "No" --> Pass Gate -- "Yes" --> Block Block --> Review Review -- "Real package, vetted" --> Allowlist Review -- "Hallucinated or typo" --> Walk classDef pr fill:#fff5f5,stroke:#cc342d,stroke-width:2.5px,color:#1a1a1a classDef gate fill:#fffbe6,stroke:#bf8a00,stroke-width:2.5px,color:#1a1a1a classDef pass fill:#f0f9f0,stroke:#2e7d32,stroke-width:2.5px,color:#1a1a1a classDef block fill:#1a1a1a,stroke:#cc342d,stroke-width:2.5px,color:#fafaf7 classDef review fill:#e8f4f8,stroke:#0277bd,stroke-width:2.5px,color:#1a1a1a classDef allow fill:#f0f9f0,stroke:#2e7d32,stroke-width:2.5px,color:#1a1a1a classDef walk fill:#f5e9ff,stroke:#7c3aed,stroke-width:2.5px,color:#1a1a1a class PR pr class Gate gate class Pass pass class Block block class Review review class Allowlist allow class Walk walk

That is it. No Snyk subscription, no Socket.dev license, no signing key infrastructure. A 20-line YAML file and one founder who reads the PR comment when it fires.

The contract clause

One paragraph. Send it as an SOW (statement of work) addendum to your existing dev shop, or paste it into the next agency MSA (master service agreement) before signing. Do not let an agency talk you out of it.

Supply-chain hygiene. Contractor will not introduce any third-party dependency (Ruby gem, PyPI package, npm module, Composer package, system library, or container base image) without prior written approval from the Founder. Approval requires (a) confirmation that the package exists on its canonical registry under the exact name proposed; (b) a published maintainer history of at least 12 months or a signed deviation memo; (c) a download / install count appropriate for the package’s stated purpose; (d) a CI dependency gate that fails the build on any unapproved new dependency. Contractor is liable for any incident traceable to a hallucinated, typosquatted, or slopsquatted dependency that was not gated. AI tooling output is contractor’s work product for the purpose of this clause; “the model suggested it” is not a defense.

A working agency signs this without renegotiating. One that fights the language is the agency where the slopsquatted gem already lives in your Gemfile.lock and they do not want to find out.

The 2026 statistics

The threat data has caught up to the technique. Snyk’s ToxicSkills audit of AI coding agent skills found that 13.4% of the audited agent skills carried at least one critical security issue (534 of 3,984 skills audited across ClawHub and skills.sh, February 2026).

GitHub’s 2025 State of the Octoverse reports that among active Copilot users, close to half the code written is now AI-generated. The supply-chain gap scales with that adoption. The discipline does not.

What to do tomorrow

Three actions. None require an engineer to start.

  • Tonight: open your Gemfile.lock / package-lock.json / requirements.txt / composer.lock. Read the package names out loud. Any name you cannot identify in 5 seconds, paste it into your registry’s search (rubygems.org, pypi.org, npmjs.com). If the package has fewer than 1,000 downloads or was first published in the last 60 days, write its name on a list and ask your dev shop in writing why it is in your codebase. Save the email - it is the start of your audit.
  • This week: drop the 20-line CI gate above into .github/workflows/dependency-gate.yml. Open the PR yourself if your dev shop is slow. The merge protection takes 10 minutes to wire in GitHub repository settings. Reference the GitHub/AWS/DB ownership checklist for repository admin access if your name is not on the org owners list.
  • Before any new SOW: paste the contract clause from this post into the addendum section. If the agency strikes the clause, that is the audit finding. The SOW reading guide covers the rest of the clauses you should be checking on the same pass.

Wrapping the course

This is the last supplementary chapter. The full artifact list (Founder OS) and the module map live on the course landing page - the “start here if…” note on each module routes you back to the right entry point.

Further reading


Built by JetThoughts as part of the From Idea to First Paying Customer curriculum.

If you finished the course end-to-end, drop a note or ping @jetthoughts on X - we would love to hear what you shipped.