https://github.com/snailsploit/snail-url
Snail-Url is Yet another Wrapper for Open Redirect finding,
https://github.com/snailsploit/snail-url
docker openredirect-scanner penetration-testing ptsnails
Last synced: about 1 month ago
JSON representation
Snail-Url is Yet another Wrapper for Open Redirect finding,
- Host: GitHub
- URL: https://github.com/snailsploit/snail-url
- Owner: SnailSploit
- Created: 2025-03-02T15:25:35.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-02T15:54:31.000Z (over 1 year ago)
- Last Synced: 2025-03-02T16:33:44.660Z (over 1 year ago)
- Topics: docker, openredirect-scanner, penetration-testing, ptsnails
- Language: Python
- Homepage:
- Size: 11.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Snail-url
**Async open-redirect hunter** for red teams and appsec engineers.
Crawls, harvests redirect-prone URLs, injects payloads, and confirms real open redirects via HTTP 30x, HTML meta refresh, and common JS redirects.
> β οΈ **Legal/Ethical**: Use only on assets you own or are authorized to test. You are responsible for complying with all laws and terms of service.
---
## Highlights
* β‘ **Fast & async** (aiohttp) with **per-host rate limiting**
* π§ **Crawler fallback** (scope-aware) to discover targets when you donβt have a URL list
* π§ͺ **Payload strategy sets**: `basic`, `aggressive`, `stealth` (and custom test domain)
* π **SAML / OIDC** focus: `RelayState`, `redirect_uri`, `returnTo`, `continue`, etc.
* π€ **Outputs**: JSON, NDJSON, CSV + optional dump of unverified candidates
* π₯οΈ **Pretty CLI**: compact, padded tables that donβt overflow your terminal
---
## Install
### Local
```bash
git clone https://github.com//snail-url.git
cd snail-url
python3 -m venv .venv && source .venv/bin/activate
pip install --upgrade pip
pip install -e .
```
### Docker
```bash
docker build -t snail-url:latest .
# mount current folder for saving results
docker run --rm -v "$(pwd)":/scan snail-url:latest \
snail-url -d example.com --crawl --max-pages 2000 --json-out /scan/results.json
```
---
## Quick start
Basic run (no crawl):
```bash
snail-url -d example.com --json-out results.json
```
Crawler fallback + aggressive payloads:
```bash
snail-url -d example.com \
--crawl --max-pages 2000 \
--payload-set aggressive \
--include-subdomains \
--samloidc \
--pretty --max-col 100 \
--json-out results.json --csv-out results.csv
```
Use a custom callback/test domain:
```bash
snail-url -d example.com --test-domain https://red.example/cb --json-out results.json
```
Scan a pre-collected list instead of crawling:
```bash
snail-url --in urls.txt --json-out results.json --pretty
```
Dump the **unverified** candidate list for manual review:
```bash
snail-url -d example.com --crawl --candidates-out candidates.txt
```
---
## CLI
```
snail-url [-d DOMAIN] [--seed URL ...] [--in FILE] [--crawl]
[--include-subdomains] [--respect-robots]
[--max-pages N] [-c N] [--per-host N]
[--payload-set {basic,aggressive,stealth}]
[--test-domain URL]
[--json-out FILE] [--ndjson-out FILE] [--csv-out FILE]
[--candidates-out FILE] [--user-agent UA] [--samloidc]
[--pretty] [--no-banner] [--max-col N]
```
**Most useful flags**
* `-d, --domain` β target registrable domain (sets default scope/seed)
* `--seed` β one or more starting URLs (repeatable)
* `--in` β file with URLs to check (one per line)
* `--crawl` β enable crawler fallback (async, scope-aware)
* `--include-subdomains` β widen scope to subdomains
* `--max-pages` β crawl budget (default: 2000)
* `-c, --concurrency` β global concurrency (default: 40)
* `--per-host` β per-host concurrency limit (default: 10)
* `--payload-set` β `basic` | `aggressive` | `stealth`
* `--test-domain` β destination injected into redirect params
* `--samloidc` β prioritize SAML/OIDC keys (`RelayState`, `redirect_uri`, etc.)
* `--pretty`, `--max-col` β tidy, padded table output
* `--json-out`, `--ndjson-out`, `--csv-out` β choose one or many
---
## What gets detected
* **HTTP redirects**: 30x with `Location` pointing to your **test domain**
* **HTML Meta Refresh**: e.g., ``
* **JS redirects**: `location =`, `location.replace()`, `location.assign()`
**Redirect-ish parameters** (partial list):
`redirect`, `redirect_uri`, `url`, `next`, `dest`, `destination`, `return`, `returnTo`, `continue`, `cb`, `RelayState`, etc.
**SAML/OIDC** heuristics (when `--samloidc`):
* Detects SAML-ish or OIDC-ish endpoints (`/saml/...`, `/oauth*/authorize`, `/callback`).
* Elevates `RelayState` and `redirect_uri` for injection.
---
## Output examples
### JSON
```json
[
{
"original": "https://app.example.com/redirect?redirect_uri=/dashboard",
"confirmed": true,
"param": "redirect_uri",
"payload": "https://red.example/cb",
"mutated": "https://app.example.com/redirect?redirect_uri=https%3A%2F%2Fred.example%2Fcb",
"via": "http_redirect",
"status": 302,
"location": "https://red.example/cb"
}
]
```
### NDJSON
```
{"original":"https://...","confirmed":true,"param":"redirect","via":"html/js_redirect","status":200,...}
```
### CSV (columns vary with data)
```
confirmed,param,original,mutated,via,status,location,payload
true,redirect_uri,https://...,https://...,http_redirect,302,https://red.example/cb,https://red.example/cb
```
---
## How it works (high-level)
```
Seeds/URLs
βββΊ Crawler (optional) ββΊ Harvester (redirect-ish params)
βββΊ Verifier (payload sets, no-follow)
βββΊ Findings (JSON/NDJSON/CSV)
```
* **Crawler**: async fetch, extracts links, respects scope, per-host RL.
* **Harvester**: filters URLs with redirect-ish parameters.
* **Verifier**: injects payloads β checks 30x `Location`, meta refresh, JS redirect.
---
## Tuning & tips
* **Throughput**: Bump `-c` but keep `--per-host` reasonable (8β12) to reduce server strain.
* **Noise**: Use `--payload-set stealth` for low-touch passes; `aggressive` when you need depth.
* **Scope**: Start narrow (`-d`) and add `--include-subdomains` if needed.
* **Crawler budget**: Increase `--max-pages` for large estates; capture candidates via `--candidates-out`.
* **User-Agent**: Customize with `--user-agent` for logs/attribution.
---
## Troubleshooting
* **No findings but many candidates**
Targets might block external destinations; try different `--payload-set` or `--test-domain`.
* **Timeouts**
Reduce `-c` and `--per-host`; some WAFs throttle concurrency.
* **Messy terminal output**
Use `--pretty --max-col 100` (table is padded & ellipsized). Use `--no-banner` to minimize whitespace.
---
## Development
```bash
# lint/format as you like; basic tests included
pytest -q
```
Project layout:
```
snail_url/
cli.py # CLI entry
crawler.py # async crawler (scope-aware)
harvester.py # picks redirect-like URLs
verifier.py # injects payloads, confirms redirects
payloads.py # basic/aggressive/stealth generators
saml_oidc.py # SAML/OIDC heuristics
ui.py # pretty table output
utils.py, constants.py, output.py
```
---
## Roadmap
* Optional archive sources (Wayback, GAU) as inputs
* SARIF exporter for CI
* Parameter mutation strategies by framework (Next.js, Spring, ASP.NET)
* Allow/deny-lists per path/param
---
## Contributing
PRs and issues welcome. Please include:
* Clear repro steps (target pattern anonymized)
* Before/after output snippets
* Any performance/safety considerations
---
## License
MIT Β© SnailSploit
---
Want me to drop this straight into your repo as `README.md` (and add status badges)? Say the word and Iβll prep a PR description and push-ready commit message.
---
## π Documentation & Author
This project's full writeup, methodology, and related research lives at:
**[https://snailsploit.com/tools](https://snailsploit.com/tools)**
Created by **Kai Aizen** β independent offensive security researcher.
[snailsploit.com](https://snailsploit.com) Β· [Research](https://snailsploit.com/research) Β· [Frameworks](https://snailsploit.com/frameworks) Β· [GitHub](https://github.com/SnailSploit) Β· [LinkedIn](https://linkedin.com/in/kaiaizen) Β· [ResearchGate](https://www.researchgate.net/profile/Kai-Aizen-2) Β· [X/Twitter](https://x.com/SnailSploit)
> *Same attack. Different substrate.*