A small, educational Python scanner that crawls a web app and checks for:
- Reflected XSS — injects a script payload into URL params and form fields, checks whether it comes back unescaped
- SQL injection (error-based) — injects quote/logic payloads, looks for database error signatures in the response
- Security misconfigurations — missing security headers (CSP, X-Frame-Options, HSTS, etc.), insecure cookies (missing
Secure/HttpOnly), verbose server/tech banners, directory listing
Only scan applications you own or are explicitly authorized to test. Use a local lab like OWASP Juice Shop or DVWA, or your own dev environment. The tool sends real test payloads to the target. Scanning systems without authorization is illegal in most places, and the CLI will ask you to confirm authorization before it runs (unless you pass
-y).
pip install -r requirements.txtpython main.py http://localhost:3000Options:
| Flag | Description |
|---|---|
--max-pages N |
Max pages to crawl (default 25) |
--timeout N |
Request timeout in seconds (default 10) |
--json FILE |
Write a JSON report to FILE |
-y, --yes |
Skip the authorization confirmation prompt |
--skip xss sqli headers cookies dirlisting |
Skip specific check categories |
Example:
python main.py http://localhost:3000 --max-pages 50 --json report.json --skip dirlistingscanner/
crawler.py # BFS crawl of same-domain pages, discovers <a href> links and <form> fields
checks.py # XSS / SQLi / header / cookie / dir-listing check functions, return Finding objects
report.py # console + JSON report rendering
main.py # CLI glue: crawl -> run checks -> report
The crawler tracks two things:
pages— HTML pages, used to discover more links/forms and to check headers/cookiesall_urls— every URL fetched regardless of content type, so param-based checks (XSS/SQLi) also reach JSON API endpoints, not just HTML pages
A tiny intentionally-vulnerable Flask app is included under test_target/ for trying the scanner safely:
pip install flask
python test_target/vulnerable_app.py # runs on http://127.0.0.1:5055
# in another terminal:
python main.py http://127.0.0.1:5055/ -yIt has a reflected-XSS endpoint (/search?q=), a SQL-injectable endpoint (/user?id=), and a login form — good for confirming each check fires correctly.
- No JavaScript rendering — won't find links/forms injected by client-side JS (SPAs). A real scanner would need a headless browser (Playwright/Selenium).
- Signature-based SQLi detection only — catches error-based SQLi; won't catch blind/time-based/boolean-based SQLi. Extending this would mean adding response-diffing and timing-based payloads.
- XSS detection is naive — checks for raw reflection of a
<script>tag; doesn't handle context-aware injection (attribute context, JS string context, DOM-based XSS) or bypass encodings. - No authentication handling — can't crawl behind a login wall unless you pre-populate
sessionwith cookies/tokens yourself. - Single-threaded — sequential requests, so scans are slow on larger sites. Adding a thread pool / async requests would speed this up significantly.
- No CSRF-aware form submission ordering, no rate limiting/backoff, no WAF-evasion — none of that is included on purpose, since this is meant for learning against apps you control.
- Add CSRF token handling when submitting forms
- Add a headless-browser crawl mode for JS-heavy apps
- Add more misconfig checks (CORS wildcard, exposed
.git/.env, default credentials) - Add authenticated scanning (pass in cookies/headers)
- Rate-limit requests to avoid overwhelming the target