What it detects
Offline, stdlib-only Python 3 CLI that flags hallucinated-package / slopsquatting risk in the dependency lists and imports that AI coding assistants produce.
AI assistants sometimes invent plausible package names (langchain-utils-pro, python-openai-helper) or make typos (reqeusts). Attackers can register those names ("slopsquatting") and wait for someone to install them. slopcheck gives you a quick, offline first pass so you know which names to go verify by hand.
Rules
| ID | Severity | Meaning |
|---|---|---|
| SC01 | info | Not in snapshot or allowlist: unverified, check the registry yourself |
| SC02 | high | Near-miss of a well-known name: Damerau-Levenshtein ≤1 (names ≤6 chars) or ≤2, separator confusion (pythondateutil), npm case confusion (React) |
| SC03 | medium | Hallucination shape: popular base + generic affixes (-utils, -helper, -sdk, -api, -py, python-, -js, -pro, ...) where the combination is unknown |
| SC04 | medium | Ecosystem confusion: npm-only name in Python deps (axios in requirements.txt) or vice versa |
| SC05 | low | Unpinned / loose version (pandas, >=1.0, *, latest) |
| SC06 | medium | Direct URL / VCS / git dependency bypasses the registry |
| SC07 | low | Imported but not declared (only when manifests and sources of that ecosystem are scanned) |
| SC08 | low | Declared but never imported (dev deps and common tools like pytest/black are skipped) |
Usage
python3 slopcheck.py [PATHS ...] # files or directories, default "."
--allow FILE allowlist, one name per line (# comments ok; repeatable)
--known FILE use another snapshot JSON ({"pypi": [...], "npm": [...]})
--json | --sarif JSON or SARIF 2.1.0 output (default: text table)
--min-severity LEVEL info|low|medium|high (default info)
--fail-on LEVEL high|medium|low|any|none (default high) -> exit 1
--no-usage skip SC07/SC08
--list-rulesAfter pip install of the kit, the same options work as agentsec slopcheck …. Every tool also accepts --help and almost every tool accepts --json.
Example output
The full examples/risky/ directory (requirements.txt + package.json + app.py + index.js, all fake names, do not install) produces 41 findings (7 high) and exits 1; examples/clean/ produces no findings and exits 0.
CI example:
$ python3 slopcheck.py examples/risky/requirements.txt --no-usage
SEV RULE ECO NAME LOCATION MESSAGE
HIGH SC02 pypi reqeusts examples/risky/requirements.txt:2 'reqeusts' is a near-miss of well-known 'requests' (edit distance 1); possible typo or slopsquat
HIGH SC02 pypi beautifulsoup examples/risky/requirements.txt:7 'beautifulsoup' is a near-miss of well-known 'beautifulsoup4' (edit distance 1); possible typo or slopsquat
MEDIUM SC03 pypi langchain-utils-pro examples/risky/requirements.txt:4 'langchain-utils-pro' = popular 'langchain' + generic affix(es) pro/utils; a common shape of AI-hallucinated names
MEDIUM SC03 pypi python-openai-helper examples/risky/requirements.txt:5 'python-openai-helper' = popular 'openai' + generic affix(es) helper/python; a common shape of AI-hallucinated names
MEDIUM SC04 pypi axios examples/risky/requirements.txt:8 'axios' is a well-known npm package but not a known pypi one; likely wrong ecosystem
MEDIUM SC06 pypi somepkg examples/risky/requirements.txt:9 direct URL/VCS dependency (git+https://github.com/example/somepkg.git#egg=somepkg) bypasses the registry; pin a commit hash and review the source
LOW SC05 pypi numpy examples/risky/requirements.txt:3 loose version '>=1.26' (no upper bound or exact pin)
LOW SC05 pypi python-openai-helper examples/risky/requirements.txt:5 no version pin; an attacker-registered or changed release would be picked up automatically
LOW SC05 pypi pandas examples/risky/requirements.txt:6 no version pin; an attacker-registered or changed release would be picked up automatically
LOW SC05 pypi beautifulsoup examples/risky/requirements.txt:7 no version pin; an attacker-registered or changed release would be picked up automatically
INFO SC01 pypi somepkg examples/risky/requirements.txt:9 'somepkg' is not in the bundled snapshot or allowlist: unverified, check the registry yourself
11 finding(s): 2 high, 4 medium, 4 low, 1 info (1 file(s) scanned)
note: snapshot-based offline heuristics; cannot confirm a package exists or is safe. Verify flagged names on pypi.org / npmjs.com yourself.
$ echo $?
1
SARIF and CI
agentsec slopcheck path/to/input --sarif > slopcheck.sarif
# GitHub Actions (composite action ships with the repo)
- uses: dunkleschitz/agentsec@v0
with:
tools: slopcheck
paths: path/to/input
fail-on: high
SARIF 2.1.0 can be uploaded to GitHub code scanning. The composite action writes per-tool reports under agentsec-sarif/ by default.
OWASP mapping
Heuristic mapping of what this tool helps a reviewer look for. Not an official OWASP endorsement, and not complete coverage of any item. Sources: OWASP Top 10 for LLM Applications 2025 and OWASP Top 10 for Agentic Applications 2026.
- LLM03 Supply Chain — OWASP LLM Top 10 (2025)
- LLM09 Misinformation — OWASP LLM Top 10 (2025)
- ASI04 Agentic Supply Chain Vulnerabilities — OWASP Agentic Top 10 (2026)
Known limits
Heuristic scanner, not a security boundary. A clean result does not mean something is safe. All example secrets in this repository are fake.
Full source, tests, and fixtures: tools/slopcheck/ in the repository. Install the kit with pip install git+https://github.com/dunkleschitz/agentsec.git.