A security auditor CLI for Git repositories using LLMs
Project description
๐ธ๏ธsnitch-stitch
A security auditor CLI for Git repositories. Scans both backend source code and running frontend UIs to find real security vulnerabilities, scores them by severity, and lets you accept or reject LLM-generated code fixes.
Installation
pip install snitch-stitch
Or install from source:
git clone https://github.com/snitch-stitch/snitch-stitch.git
cd snitch-stitch
pip install -e .
Requirements
snitch-stitch uses litellm to support multiple LLM providers. Set the API key for whichever provider you want to use:
Environment Variables
| Variable | Required for | Description |
|---|---|---|
OPENAI_API_KEY |
OpenAI models (default) | e.g. gpt-4o, gpt-4-turbo |
ANTHROPIC_API_KEY |
Anthropic models | e.g. claude-sonnet-4-5-20250929 |
GEMINI_API_KEY |
Google models | e.g. gemini/gemini-1.5-pro |
RTRVR_API_KEY |
No | Used for frontend browser scanning via rtrvr.ai |
# OpenAI (default)
export OPENAI_API_KEY="sk-..."
# Or Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
# Or Google
export GEMINI_API_KEY="..."
# Optional: frontend scanning
export RTRVR_API_KEY="..."
Usage
snitch-stitch <repo-path> [options]
Arguments
<repo-path>- Path to the local repository directory to scan (required)
Options
| Flag | Description | Default |
|---|---|---|
--model MODEL |
LLM model to use via litellm (see examples below) | gpt-4o |
--frontend-url URL |
URL of a running frontend (e.g., http://localhost:3000). Enables frontend scanning. |
None |
--fix-all |
Skip the selection prompt and attempt to fix everything | False |
--dry-run |
Show diffs but never write anything to disk | False |
--verbose |
Print debug info (raw API responses, parsed JSON) | False |
Model Examples
# OpenAI (default)
snitch-stitch ./my-project --model gpt-4o
snitch-stitch ./my-project --model gpt-4-turbo
# Anthropic
snitch-stitch ./my-project --model claude-sonnet-4-5-20250929
# Google Gemini
snitch-stitch ./my-project --model gemini/gemini-1.5-pro
# Azure OpenAI
snitch-stitch ./my-project --model azure/my-deployment-name
Any model supported by litellm can be used.
Examples
Scan a repository for backend vulnerabilities:
snitch-stitch ./my-project
Scan both backend and frontend:
snitch-stitch ./my-project --frontend-url http://localhost:3000
Preview fixes without applying them:
snitch-stitch ./my-project --dry-run
Automatically fix all vulnerabilities:
snitch-stitch ./my-project --fix-all
How It Works
snitch-stitch runs through 5 stages:
Stage 1: Ingest
Converts the repository into a text format suitable for LLM analysis using gitingest.
Stage 2: Backend Scan
Sends the code to the configured LLM with a security analysis prompt. Identifies vulnerabilities like:
- SQL injection
- Command injection
- Path traversal
- Hardcoded secrets
- Missing authentication
- Insecure deserialization
- XSS vulnerabilities
Stage 3: Frontend Scan (Optional)
If --frontend-url is provided and RTRVR_API_KEY is set, uses rtrvr.ai to control a real browser and probe the running application for:
- XSS (Cross-Site Scripting)
- Authentication bypass
- IDOR (Insecure Direct Object Reference)
- Missing input validation
- Admin panel access
Stage 4: Rank
Scores each vulnerability (0-10) based on:
- Exposure: Public-facing (5) vs local-only (1)
- Exploitability: Easy (3) / Moderate (2) / Hard (1)
- Impact: Critical (4) / High (3) / Medium (2) / Low (1)
Severity labels: Critical (9-10), High (7-8), Medium (4-6), Low (1-3)
Stage 5: Fix
For each selected vulnerability:
- Generates a minimal code fix using the configured LLM
- Shows a colored diff (red for removals, green for additions)
- Prompts you to accept or reject
- Writes accepted fixes to disk
Example Output
$ snitch-stitch ./my-project --frontend-url http://localhost:3000
[1/5] Ingesting repository...
โ Ingested 47 files (82 KB)
[2/5] Scanning backend code (model: gpt-4o)...
Analyzing code... done.
โ Found 4 backend vulnerabilities
[3/5] Scanning frontend...
โ Found 2 frontend vulnerabilities
[4/5] Ranking findings...
โ Ranked 6 findings
[5/5] Review and fix
โโโโโโฆโโโโโโโโโโโฆโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฆโโโโโโโโ
โ # โ Severity โ Title โ Score โ
โ โโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโฃ
โ 1 โ Critical โ SQL injection in /api/login โ 10 โ
โ 2 โ Critical โ Hardcoded AWS key in settings.py โ 9 โ
โ 3 โ High โ Command injection in file converter โ 8 โ
โ 4 โ High โ Missing auth on /api/admin/users โ 7 โ
โ 5 โ Medium โ XSS in search input โ 5 โ
โ 6 โ Low โ No input validation on age field โ 3 โ
โโโโโโฉโโโโโโโโโโโฉโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉโโโโโโโโ
Select vulnerabilities to fix (comma-separated numbers, or 'all'):
> 1, 2
--- Generating fix for: SQL injection in /api/login ---
Generating fix... done.
app/auth.py
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
def login(username, password):
- query = f"SELECT * FROM users WHERE username = '{username}'"
- cursor.execute(query)
+ query = "SELECT * FROM users WHERE username = %s"
+ cursor.execute(query, (username,))
user = cursor.fetchone()
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Apply this fix? [y/n/a=accept all]: y
โ Fixed: app/auth.py
Vulnerability Classes Detected
| Class | Description |
|---|---|
sqli |
SQL injection via string concatenation |
command_injection |
Shell command injection via os.system, subprocess |
path_traversal |
Directory traversal allowing file access |
ssrf |
Server-side request forgery |
deserialization |
Insecure deserialization (pickle, yaml) |
xss |
Cross-site scripting |
secrets_exposure |
Hardcoded API keys, passwords, tokens |
authz |
Missing or broken authorization |
idor |
Insecure direct object references |
input_validation |
Missing input validation |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file snitch_stitch-0.2.0.tar.gz.
File metadata
- Download URL: snitch_stitch-0.2.0.tar.gz
- Upload date:
- Size: 30.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11df825fe3fc06566b44b0bfde6825b4314e9e69e5c704459d3dfbbcb521c512
|
|
| MD5 |
070a9e06d1d492ad9addf90ebc6ce56e
|
|
| BLAKE2b-256 |
171bf5e006735c537638baa6067e4e6e57950a02e39025dcb8227773e2964b8f
|
File details
Details for the file snitch_stitch-0.2.0-py3-none-any.whl.
File metadata
- Download URL: snitch_stitch-0.2.0-py3-none-any.whl
- Upload date:
- Size: 31.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc0cb91496e8f9e145a39e9e2191322275a9ffb997a129a9a324c15708dae148
|
|
| MD5 |
db6d764f0e045911fd8c82cb736110c2
|
|
| BLAKE2b-256 |
f181be93b0d5d9f1ff839d1101ac25918ba081e0e13f778b08b1ec5f4bde9697
|