twgnr/web-vulnerability-scanner
GitHub: twgnr/web-vulnerability-scanner
一款专为授权测试设计的非破坏性 Python Web 漏洞扫描器,提供从爬取、注入检测到合规映射与修复追踪的完整安全评估能力。
Stars: 1 | Forks: 0
# web-vuln-scanner
Ein leichtgewichtiger, **defensiver** Web-Schwachstellen-Scanner in Python für
**autorisierte** Sicherheitstests (Pentest deiner eigenen oder freigegebenen Systeme).
## ⚠️ Rechtlicher Hinweis
Setze dieses Tool **ausschließlich** gegen Systeme ein, die dir gehören oder für
die du eine **ausdrückliche, schriftliche Erlaubnis** hast. Unbefugtes Scannen
fremder Systeme kann in vielen Ländern strafbar sein (in DE z.B. § 202a/c StGB).
Das Tool fragt vor jedem Scan eine Autorisierungs-Bestätigung ab.
Der Scanner ist **nicht-destruktiv**: Er verändert keine Daten und nutzt keine
zerstörerischen Payloads (kein DROP/DELETE, keine Stacked Queries, kein DoS).
## Installation
cd C:\Repository\web-vuln-scanner
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
## Verwendung
# Vollständiger Scan (alle Checks)
python scan.py "https://example.com/seite?id=1"
# Nur bestimmte Checks
python scan.py "https://example.com" --checks headers,tls,cookies
# Mit zeit-basierten SQLi-Tests (langsamer, treffsicherer)
python scan.py "https://example.com/produkt?id=42" --time-based
# Höflicher/leiser Scan + Ergebnis als JSON
python scan.py "https://example.com" --delay 0.5 --json ergebnis.json
# Test-/Staging-System mit Self-signed-Zertifikat
python scan.py "https://localhost:8443/app?q=test" --insecure
| Option | Wirkung |
|----------------|---------|
| `--checks` | Auswahl aus den Check-Namen (siehe „Was wird geprüft?": `headers,tls,…,node,wordpress,network,api,traversal,jwt,pwmgr,pollution,dotnet,java,python,cms`) oder `all` |
| `--timeout` | Request-Timeout in Sekunden (Standard 10) |
| `--delay` | Pause zwischen Requests (rücksichtsvoller Scan) |
| `--insecure` | TLS-Zertifikat nicht prüfen |
| `--time-based` | Zeit-basierte SQLi-/Command-Injection-Erkennung aktivieren |
| `--crawl` | Same-origin crawlen und die Injection-Checks auf allen entdeckten Seiten ausführen |
| `--max-pages N` | Crawl: max. Seitenzahl (Standard 500) |
| `--max-depth N` | Crawl: max. Link-Tiefe (Standard 8) |
| `--discover` | API-/Pfad-Discovery (OpenAPI, JS-Endpoints, robots/sitemap, Backups, OIDC) → entdeckte Endpunkte testen |
| `--ssrf-callback HOST` | Eigener (externer) OOB-Callback-Host für den SSRF-Check |
| `--ssrf-auto` | Blind-SSRF automatisch nachweisen via eingebautem lokalem Listener |
| `--ssrf-listen-host HOST` | OOB-Listener-Adresse: `127.0.0.1` (Standard), `auto` (Egress-IP) oder IP/Tunnel-Host |
| `--faq` | Erklärt, was mit welcher Option geprüft wird und welche Eingaben erwartet werden (beendet danach) |
| `--asvs` | Zusätzlich einen ASVS-5.0-Report (automatisierte Prüfungen) erstellen |
| `--legal` | Rechtlicher Compliance-Report (DE): Impressum, DSGVO, Cookies, SEO, Barrierefreiheit (Heuristik) |
| `--browser` | Mit `--legal`: gerendertes WCAG-Audit via Headless-Browser (Playwright+axe-core) |
| `--verify` | Verifizierbare Befunde aktiv & nicht-destruktiv bestätigen |
| `--no-cve-online` | Online-CVE-Abgleich (NVD) abschalten – nur mitgelieferte Liste |
| `--cve-refresh` | Lokalen CVE-Cache ignorieren und frisch von der NVD laden |
| `--cve-max N` | Max. Online-CVEs je Komponente (Standard 25, nach Schweregrad) |
| `--ratelimit-burst N` | Anfragen für die Rate-Limit-Probe des `network`-Checks (5–40, Standard 20; kein Lasttest) |
| `--profile P` | Scan-Profil `quick` (schnelle Essentials), `full` (alle), `safe` (ohne aggressivere Proben); überschreibt `--checks` |
| `--concurrency N` | Parallele Worker für die Per-URL-Checks beim Crawl/Discovery (Standard 1) |
| `--proxy URL` | Alle Anfragen über einen HTTP/S-Proxy leiten (z. B. Burp/ZAP: `http://127.0.0.1:8080`) |
| `--scope` / `--allow-host H` | Nur Ziel-Host (+ Subdomains, + erlaubte Hosts) anfragen; alles andere wird blockiert & protokolliert |
| `--audit-log DATEI` | Jede gesendete Anfrage (Zeit/Methode/URL/Status) als JSONL protokollieren |
| `--sarif DATEI` | Befunde als SARIF 2.1.0 speichern (CI / GitHub Code Scanning) |
| `--track` | Scan in der lokalen Historie festhalten und die **Drift** (neu/behoben/unverändert) ggü. dem letzten Lauf anzeigen |
| `--controls` | **Compliance-Mapping**: Befunde auf SOC-2- und ISO-27001-Kontrollen abbilden (nur extern prüfbarer Anteil) |
| `--remediation` | Gespeicherten **Remediation-Status** je Befund laden und den offenen Rückstand anzeigen |
| `--set-status FP=STATUS` | Remediation-Status eines Befunds setzen (`OPEN`/`IN_PROGRESS`/`RESOLVED`/`RISK_ACCEPTED`/`FALSE_POSITIVE`); mehrfach angebbar. Zusätzlich `--status-owner`/`--status-note`/`--status-due` |
| `--evidence DATEI` | Audit-fähiges **Evidence-Bundle** (Befunde + Verifikation + Controls + Remediation + Drift) als JSON speichern |
| `--history-dir DIR` | Abweichender Basisordner für Historie/Remediation (Standard: `%LOCALAPPDATA%/web-vuln-scanner`) |
| `--no-tech` | Technologie-Erkennung (Tech-Stack-Übersicht) abschalten (standardmäßig an) |
| `--analyze` | Zusätzliche Website-Analyse: Performance, SEO, DNS/E-Mail, Erreichbarkeit & Tracker/Privacy |
| `--mxtools` | DNS/Registrar-Prüfungen (Records, SPF/DMARC/DKIM/MTA-STS/BIMI/TLS-RPT, RDAP, DNSBL, SMTP) |
| `--json DATEI` | Befunde zusätzlich als JSON speichern |
| `--yes` | Autorisierungs-Abfrage überspringen |
## Mehrseitige Prüfung (Crawler)
**Standardmäßig wird nur die eingegebene URL geprüft** (plus die kuratierten Pfad-
Listen einzelner Checks und die Formulare auf genau dieser Seite). Der Scanner
crawlt die Anwendung also *nicht* von sich aus.
Mit `--crawl` (CLI) bzw. dem Häkchen **„Ganze App crawlen"** in der Web-UI entdeckt
der Scanner alle verlinkten Seiten **derselben Origin** und führt die parameter-/
seitenbezogenen Injection-Checks (**SQLi, XSS, NoSQLi, Command Injection, Open
Redirect**) auf jeder entdeckten Seite und jedem Formular aus.
python scan.py "https://meine-app.de/" --crawl --max-pages 500 --max-depth 8
- **Nur GET, nicht-destruktiv:** Potenziell zustandsändernde Links (logout, delete,
reset, remove …) werden grundsätzlich übersprungen – ein eingeloggter Crawl löst
also nichts aus.
- **Nutzt die Login-Session**, falls per `--auth-method` gesetzt (findet Seiten
hinter dem Login), sonst anonym.
- **Eingrenzung gegen endloses Crawlen:** nur dieselbe Origin, `--max-pages`/
`--max-depth`, und Dedup nach (Pfad + Parameter-**Namen**) – `?id=1` und `?id=2`
zählen als eine Seite. Doppelte Funde werden zusammengeführt.
- Host-/Konfig-Checks (TLS, DNS, Header, DB-Exposition …) laufen weiterhin einmal
auf der Start-URL; der Crawl erweitert gezielt die Injection-Abdeckung.
- **Die entdeckten Seiten werden aufgelistet:** in der Web-UI im Tab **„Seiten"**
(Status, Tiefe, Titel, Formular-/Parameter-Merkmale, Markierung „Befund" bei
Treffern; inkl. der via Discovery gefundenen API-Endpunkte), auf der CLI als
kompakte Liste und im HTML-/JSON-Export als eigener Abschnitt.
- **Auch der ASVS-Report wird beim Crawlen mehrseitig** (`--crawl --asvs`): die
seitenspezifischen Kategorien (Validierung, Sitzungsmanagement, Authentifizierung)
werden über alle entdeckten Seiten ausgewertet und je Anforderung **App-weit
aggregiert** (schlimmster Status gewinnt, betroffene Seiten werden gelistet);
host-weite Kategorien (Architektur, Zugriffskontrolle, Kryptographie) bleiben einmalig.
## API-/Pfad-Discovery (für SPAs)
Bei Single-Page-Apps findet der Link-Crawler kaum etwas – die Angriffsfläche steckt
in der **API**. Mit `--discover` (CLI) bzw. dem Häkchen **„API/Pfade entdecken"**
entdeckt der Scanner rein lesend zusätzliche Endpunkte und speist sie in die
Injection-Checks ein:
- **OpenAPI/Swagger** wird gefunden **und geparst** → konkrete Endpunkt-URLs (Pfad-/
Query-Parameter mit Platzhaltern gefüllt).
- **JS-Endpoint-Mining**: API-Pfade aus gleich-origin JavaScript-Bundles.
- **robots.txt + sitemap.xml** als zusätzliche Pfadquelle.
- **Backup-/Source-Varianten** entdeckter Code-/Config-Dateien (`.bak`/`~`/`.old` …).
- **OIDC**: `/.well-known/openid-configuration` (z. B. Endpunkte über HTTP → Fund).
python scan.py "https://app.de/" --discover --crawl # Crawl + Discovery kombiniert
## Erweiterte Auth-/Mehrkonten-Tests
Über den Standard hinaus lassen sich Login- und Berechtigungs-Schwächen aktiv (aber
nicht-destruktiv) prüfen:
# Session Fixation + Brute-Force-Schutz (braucht Formular-Login)
$env:SCAN_PASSWORD = "geheim"
python scan.py "https://app.de/dashboard" --auth-method form `
--login-url "https://app.de/login" --username alice --success-indicator "Logout" --auth-tests
# Login-Test mit EIGENEN Login-Daten (unabhängig von der Haupt-Auth-Methode):
# Hauptscan per Cookie, Brute-Force/Fixation aber gegen das Login-Formular
python scan.py "https://app.de/" --auth-method cookie --cookie "pm_session=..." `
--auth-tests --login-url "https://app.de/login" --username alice --success-indicator "Logout"
# Tenant Isolation + Privilege Escalation (zweites Konto), am besten mit --crawl
python scan.py "https://app.de/konto?id=1" --auth-method cookie --cookie "pm_session=A..." `
--second-cookie "pm_session=B..." --crawl
# Passwort-Richtlinie (OPT-IN, zustandsändernd – legt ggf. Test-Konten an)
python scan.py "https://app.de/" --password-policy-url "https://app.de/register"
python scan.py "https://app.de/" --password-policy-auto # Endpoint automatisch suchen & testen
| Test | Was & Grenzen |
|------|----------------|
| **Session Fixation** (`--auth-tests`) | Meldet sich einmal an und prüft, ob die Session-ID rotiert. Eigene Login-Daten (`--login-url/--username/--password` …) oder Form-Auth. |
| **Brute-Force-Schutz** (`--auth-tests`) | ≤15 Fehl-Logins mit **Fake-Benutzer** → greift Rate-Limit/Lockout/Verzögerung? Sperrt kein echtes Konto. |
| **Tenant Isolation / Privilege Escalation** (`--second-cookie`) | Liest Konto B objektbezogene Daten (id-Parameter) von A bzw. Admin-Bereiche? Rein lesend, Funde „vermutet" (Rolle/Mandant manuell bestätigen). |
| **Passwort-Richtlinie** (`--password-policy-url` / `--password-policy-auto`) | Opt-in, **zustandsändernd**: prüft, ob triviale Passwörter akzeptiert werden. `--password-policy-auto` sucht den Endpoint read-only und testet nur den besten Kandidaten. |
## Authentifizierte Scans (als eingeloggter Benutzer)
Damit Tests auch hinter dem Login laufen, kann sich der Scanner anmelden. Unterstützt:
`form` (Formular-Login mit automatischer CSRF-/Hidden-Feld-Übernahme), `basic`,
`bearer`, `cookie`, `header`. Die so aufgebaute Session trägt Cookies/Header in
alle Checks.
**CLI – Formular-Login:**
# Passwort sicher über Umgebungsvariable (nicht in der Shell-History)
$env:SCAN_PASSWORD = "geheim"
python scan.py "https://meine-app.de/dashboard?id=1" `
--auth-method form --login-url "https://meine-app.de/login" `
--username alice --success-indicator "Logout"
Wird kein `--password` übergeben, fragt das Tool es verdeckt ab oder nutzt
`SCAN_PASSWORD`. Alternativ Login-Daten in einer Datei **hinterlegen**:
copy auth.example.json auth.json # Werte anpassen
python scan.py "https://meine-app.de/dashboard" --auth-config auth.json
**Weitere Verfahren:**
python scan.py URL --auth-method basic --username alice # HTTP Basic
python scan.py URL --auth-method bearer --token "eyJ..." # Bearer-Token
python scan.py URL --auth-method cookie --cookie "session=abc; x=y" # Session-Cookie
python scan.py URL --auth-method header --header "X-API-Key: 123" # Custom-Header
**Web-UI:** Im Abschnitt *Authentifizierung* das Verfahren wählen und Felder
ausfüllen. Ein Banner zeigt nach dem Start, ob der Login geklappt hat.
## Web-Oberfläche
Statt der Kommandozeile kannst du auch eine lokale Web-UI nutzen:
python webapp.py
Der Server lauscht nur auf `127.0.0.1:5000` und öffnet automatisch den Browser.
Die Oberfläche bietet Ziel-Eingabe, Check-Auswahl, Optionen, ein Pflicht-Häkchen
zur Autorisierung sowie einen Live-Fortschritt mit Ergebnis-Karten nach
Schweregrad. Optionen: `--port`, `--host`, `--no-browser`.
Ein aufklappbares **„Hilfe / FAQ"**-Panel (mit Live-Filter) erklärt direkt in der
Oberfläche jede Prüfung (*was* & *wie*) und jedes Eingabefeld (*was wird erwartet*,
*was bedeutet es*). Dieselben Inhalte gibt es in der CLI über `python scan.py --faq`.
## Technologie-Erkennung (Tech-Stack)
Bei jedem Scan wird (sofern nicht via `--no-tech` abgeschaltet) der **eingesetzte
Technologie-Stack** ermittelt – Wappalyzer-artig aus Response-Headern, `Set-Cookie`,
HTML-Signaturen und Skript-Quellen, ohne Zusatzaufwand. Erkannt werden u. a.:
- **Webserver/App-Server** (Apache, nginx, IIS, Tomcat, Jetty, Gunicorn, Werkzeug …)
- **Sprache/Runtime** (PHP, Java, **Node.js/Express**, ASP.NET, Python; **TypeScript** über
`tsconfig.json`/Source-Maps – heuristisch)
- **Backend-Frameworks** (Express, Django, Laravel, Spring Boot, ASP.NET …)
- **Frontend** (React, Vue, Angular, **Next.js**, Nuxt, Svelte, Gatsby …)
- **CMS** (**WordPress**, Drupal, Joomla, TYPO3, Shopify, Ghost …) inkl. Version
- **JS-/CSS-Bibliotheken** mit Version (jQuery, Bootstrap, lodash …), **CDN/WAF**, **Analytics**
Ausgabe mit **Konfidenz** (sicher › wahrscheinlich › möglich) im CLI-Abschnitt
„Erkannte Technologien", im Web-UI-Tab **„Technologien"** und im HTML-/JSON-Export.
## Was wird geprüft?
1. **HTTP Security Header** – CSP, HSTS, X-Frame-Options, X-Content-Type-Options,
Referrer-Policy, Permissions-Policy; verräterische Header (Server, X-Powered-By).
2. **TLS/SSL** – HTTPS vorhanden, Zertifikat gültig/Ablauf, ausgehandeltes
Protokoll, Unterstützung veralteter Protokolle (TLS 1.0/1.1).
3. **Cookie-Sicherheit** – Secure-, HttpOnly-, SameSite-Flags.
4. **Information Disclosure** – offene `.git`, `.env`, `web.config`,
`phpinfo.php`, Backups, `robots.txt`-Hinweise, aktives Directory Listing.
Mit Catch-all-/SPA-Erkennung gegen Falsch-Positive.
5. **Server-Konfiguration (Apache/NGINX)** – Versions-Fingerprint und bekannte
versionsbasierte CVEs (mitgelieferte Basis + **automatischer Online-Abgleich**
mit der NIST-NVD, siehe unten), gefährliche HTTP-Methoden (`OPTIONS`), HTTP
`TRACE`/XST, Status-Endpunkte (`mod_status`, `mod_info`, `stub_status`),
Default-Seiten.
6. **SQL Injection** – fehler-basiert (DB-Fehlersignaturen), boolean-basiert
(TRUE/FALSE-Vergleich) und optional zeit-basiert; getestet werden GET-Parameter
und auf der Seite gefundene Formulare.
7. **Reflektiertes XSS** (`xss`) – benigner Marker in GET-Parametern/Formularen;
meldet *unkodierte* Reflexion (HTML-Tag- und Attribut-Kontext).
7b. **CSRF-Schutz** (`csrf`) – zustandsändernde POST-Formulare ohne Anti-CSRF-Token,
deren Cookies auch kein SameSite bieten (rein lesend; beim Crawlen pro Seite).
8. **CORS-Konfiguration** (`cors`) – reflektierte/zu offene `Access-Control-Allow-Origin`
(besonders mit `Allow-Credentials`), Wildcard `*`, Origin `null`.
9. **Open Redirect** (`redirect`) – ungeprüfte Weiterleitungs-Parameter
(`url`/`next`/`redirect` …) auf fremde Domains (Location/Meta/JS).
10. **Auth/Session** (`authsec`) – JWT-Schwächen (`alg:none`, fehlendes `exp`,
schwaches HMAC-Secret), fehlendes `Cache-Control: no-store` auf sensiblen Seiten,
Host-Header-Injection (Reset-Poisoning), User-Enumeration.
11. **Veraltete JS-Komponenten** (`components`) – Bibliotheks-Versionen
(jQuery, Bootstrap, AngularJS, Vue, Lodash …) → NVD-Abgleich (Retire.js-Stil).
12. **Datenlecks & API-Exposition** (`leaks`) – Secrets im Quelltext (AWS/Google/Slack/
Stripe/GitHub-Keys, Private Keys), Stacktraces/Verbose Errors, offene Swagger/OpenAPI,
aktivierte GraphQL-Introspection.
13. **DNS-/E-Mail-Sicherheit** (`dns`) – SPF, DMARC, CAA, DNSSEC.
14. **Command Injection** (`cmdi`) – OS-Command-Injection-*Erkennung*: in-band per
`echo` mit Arithmetik-Beweis (kein Falsch-Positiv durch bloße Reflexion) und
optional zeit-basiert (`sleep`/`timeout`, mit `--time-based`). Nur benigne Kommandos.
15. **SSRF** (`ssrf`) – Server-Side Request Forgery: in-band Cloud-Metadata-Erkennung
(169.254.169.254) sowie optional out-of-band über einen **selbst mitgebrachten**
Callback (`--ssrf-callback`). Es wird kein Listener betrieben.
16. **Subdomain-Takeover** (`takeover`) – CNAME-Kette + Anbieter-Fingerprints
(GitHub Pages, S3, Heroku, Azure, Fastly, Shopify …).
17. **Zugriffskontrolle / Broken Access Control** (`access`, OWASP A01) – nutzt die
eingeloggte Session (read-only): privilegierte/Admin-Pfade *mit und ohne* Session
(anonym erreichbar → HIGH; nur mit Session → Rolle prüfen), 403/401-Bypass
(Pfad-/Header-Tricks) und IDOR-Heuristik (ID-Parameter read-only verändern).
18. **NoSQL-/MongoDB-Injection** (`nosqli`) – Operator-Injection in GET-Parametern/
Formularen (`param[$ne]`/`[$gt]`/`[$regex]`): fehler-basiert (Mongo/Mongoose-
Signaturen), boolean-differenziell und **Login-Auth-Bypass** (`password[$ne]=`).
19. **Datenbank-Exposition** (`database`) – kuratierte DB-Ports auf dem Ziel-Host
(MongoDB/Redis/Elasticsearch/CouchDB → Unauth-*Metadaten*-Prüfung; MySQL/PostgreSQL/
MSSQL → Port erreichbar; **Oracle** → TNS-Port + best-effort Versions-/Status-Probe),
offene DB-Admin-Oberflächen (phpMyAdmin/Adminer/Mongo-Express/Fauxton …) und
Connection-String-Leaks (mit Credentials).
20. **Template Injection** (`ssti`) – `{{61*61}}`/`${…}`/`<%=…%>` in Params/Formularen;
erscheint das berechnete Ergebnis → SSTI (RCE-Klasse). A03.
21. **CRLF / HTTP Response Splitting** (`crlf`) – Zeilenumbruch in Params injiziert
einen Test-Header in die Antwort? A03.
22. **XXE** (`xxe`) – externe XML-Entitäten an XML-Endpunkten: in-band (Fehler) +
blind via OOB-Listener (`--ssrf-auto`). A05/A03.
23. **Subresource Integrity** (`sri`) – CDN-/Fremd-Skripte ohne `integrity`. A08.
24. **Web-Cache** (`cache`) – **defensiv**: Cache-Poisoning-Anfälligkeit (unkeyed
Header reflektiert + cachebar) und Cache-Deception – immer mit Cache-Buster,
es wird nichts vergiftet. A05.
25. **Exponierte Dienste** (`services`) – riskante Ports auf dem Ziel-Host
(Telnet/SSH/SMTP/RDP/VNC/**Docker-API**/etcd/Kibana …) + Banner; unauth Docker-API = CRITICAL.
26. **Request Smuggling** (`smuggle`) – **defensiv**: toleriert der Server mehrdeutige
`CL`+`TE`-/doppelte-`CL`-Anfragen (RFC-Verstoß)? Konsistenter Body → kein Desync/Kollateral. A05.
27. **Node.js / Next.js / TypeScript** (`node`) – Stack-Fingerprint (Express
`X-Powered-By`, Next.js), exponierte Node/TS-Dateien (`package.json`, Lockfiles,
`tsconfig.json`, `next.config.js`, `.npmrc` mit Token = CRITICAL, `.env*`,
`Dockerfile`, …), **OSV-Dependency-Audit** (CVEs/GHSA für npm-Pakete aus
`package.json`/Lockfile – „remote npm audit", nur Name+Version werden gesendet),
veröffentlichte **Source-Maps** (`*.js.map`), **Dev-Builds** im Prod
(`react-dom.development.js` …) und Next.js-Spezifika (`__NEXT_DATA__`-Secret-Scan,
`/_next/image`-Metadata-SSRF-Probe). A06/A05.
28. **WordPress** (`wordpress`) – **nicht-destruktiv**: Fingerprint & Core-Version
(generator-Meta/`readme.html`/RSS) inkl. NVD-CVE-Abgleich; Plugin-/Theme-Enumeration
(aus den im HTML referenzierten Assets, Version via `readme.txt`/`style.css`);
exponierte Dateien (`wp-config.php`-Backups, `wp-content/debug.log`, `install.php`,
`readme.html`/`license.txt`, SQL-Dumps) + Directory-Listing; **XML-RPC** (ist
`xmlrpc.php` aktiv? `pingback.ping`/`system.multicall` = SSRF-/Brute-Force-
Amplification – **nur Erkennung via `system.listMethods`, kein Missbrauch**);
REST-/`?author=N`-User-Enumeration; Login-Härtung & Username-Oracle (ein
einzelner Fehlversuch, kein Brute-Force). A05/A06/A07.
29. **Server / Firewall / Netzwerk** (`network`) – **nicht-destruktiv**: WAF/CDN-/Reverse-
Proxy-Erkennung (Header/Cookies + ein harmloser Trigger-Payload; „kein WAF" als
Befund) und Roh-IP-/Default-VHost-Zugriff; **Firewall-Posture** (Connect-Scan
kuratierter Management-/App-/Monitoring-Ports → offen/geschlossen/**gefiltert** als
Firewall-Indiz); HTTP-Methoden (OPTIONS/`Allow`, **TRACE**=Cross-Site-Tracing,
PUT/DELETE/**WebDAV** nur „advertised"); **Host-Header-/`X-Forwarded-Host`-Injection**;
Server-Status-Seiten (`/server-status`, `/nginx_status`); **Rate-Limiting**-Erkennung
(gebündelte, gedeckelte Anfrageserie via `--ratelimit-burst`, **kein Lasttest**). A05/A07.
30. **API-Routen** (`api`) – **nicht-destruktiv**: klassifiziert entdeckte + konventionelle
Routen nach **Auth-Posture** (public 2xx / geschützt 401-403 / fehlt 404); sucht
sensible Default-Endpunkte (`/api`, Spring-Boot `/actuator/*` inkl. `env`/`heapdump`,
`/metrics`, `/graphql`, `/swagger-ui`, `/debug` …); prüft Methoden/**Verb-Zugriff**
(OPTIONS/`Allow`, GET 401 aber HEAD 200); scannt öffentliche Antworten auf
**Secrets/PII/Stacktraces**, offene API-Doku & **GraphQL-Introspektion** und
ungefilterte Listen-Endpunkte. A01/A05/A07.
31. **Path Traversal / LFI** (`traversal`) – **nicht-destruktiv**: injiziert `../`-Payloads
in mehreren Varianten (`....//`, URL-/Doppel-Encoding, Null-Byte, Windows-`\`) in
URL-Parameter, GET-Formularfelder und gängige Datei-Parameter; bestätigt einen Treffer
**nur über eindeutige Datei-Signaturen** (`root:x:0:0`, `[boot loader]`, `[fonts]`) →
praktisch keine Falsch-Positiven. A01/A03.
32. **JWT-Sicherheit** (`jwt`) – **offline-Analyse**: sammelt JWTs aus Cookies/Set-Cookie/
Body und prüft `alg=none`, **schwaches HMAC-Secret** (offline gegen Wortliste geknackt),
fehlendes/zu langes `exp`, sensible Claims, `kid`/`jku`-Key-Injection-Fläche. Es werden
**keine** gefälschten Tokens gesendet. A02/A07.
33. **Passwort-Manager / Krypto** (`pwmgr`) – **Gray-Box, heuristisch**: Hinweise auf
clientseitige Verschlüsselung (WebCrypto/Argon2/PBKDF2/libsodium/sjcl), KDF-
Iterationszahl, hardcodierte Secrets im Client-JS und ob die **Tresor-API Klartext
statt Ciphertext** liefert. Ersetzt keine Krypto-/Code-Review. A02/A04.
34. **Prototype Pollution & GraphQL** (`pollution`) – **nicht-destruktiv**: Client-side-PP-
Sinks (statisch im JS), Server-side-PP (GET-basierte `__proto__`-Probe, keine Mutationen),
GraphQL **Feld-Suggestion** (Schema-Leak) und fehlende **Alias-/Batch-Begrenzung**
(DoS-Verstärkung, nur wenige Aliase – kein Lasttest). A03/A05.
35. **ASP.NET / .NET** (`dotnet`) – **nicht-destruktiv**: Fingerprint (IIS, `X-AspNet(Mvc)-
Version`), `__VIEWSTATE`-Hinweis, Diagnose-Handler (`trace.axd`=Request-Log,
`elmah.axd`=Fehlerlog, `glimpse.axd`) und detaillierte .NET-Fehlerseiten (customErrors off). A05.
36. **Java / Spring / Tomcat** (`java`) – **nicht-destruktiv**: Fingerprint (Tomcat/Jetty/
Spring-Boot `X-Application-Context`), **Tomcat-Manager**/Host-Manager (offen = CRITICAL,
401 = vorhanden, **kein** Cred-Test), Spring-Whitelabel-Error, JSF-ViewState, Java-
Stacktraces und **Log4Shell/Expression-Injection in-band** (`${java:version}`-Lookups). A05/A06.
37. **Python: Django / Flask** (`python`) – **nicht-destruktiv**: Fingerprint (WSGIServer/
gunicorn/Werkzeug, Django-Cookies), **Django `DEBUG=True`** (Debug-Seite leakt URLconf/
Settings/SECRET_KEY), `/admin/`-Login und **Werkzeug-Debugger** (Flask `debug=True` → Konsole/RCE). A05.
38. **CMS: Drupal / Joomla / TYPO3** (`cms`) – **nicht-destruktiv**: Fingerprint + Core-Version
(Generator/CHANGELOG/XML) inkl. **NVD-CVE-Abgleich**, Default-/Admin-Pfade (`/user/login`,
`/administrator/`, `/typo3/`) und exponierte Konfig-/Backup-Dateien. A06.
Zusätzlich erweitert: **Security Header** prüft jetzt auch die **CSP-Qualität**
(`unsafe-inline`/`unsafe-eval`/Wildcards/fehlende Direktiven), Isolations-Header
(COOP/CORP) und **Mixed Content**; **TLS** prüft zusätzlich schwache Cipher,
Forward Secrecy, TLS 1.3 sowie Zertifikats-Schlüssellänge/Signatur.
## Automatischer CVE-Abgleich (NVD)
Beim Server-Check (`server`) erkennt der Scanner die eingesetzten Komponenten
aus den `Server`- und `X-Powered-By`-Headern – **Apache, nginx, PHP und OpenSSL** –
und gleicht jede erkannte **Version** automatisch mit der **NIST National
Vulnerability Database** (NVD, [nvd.nist.gov](https://nvd.nist.gov)) ab – einer
kostenlosen, offiziellen CVE-Quelle. Die mitgelieferte Offline-Liste (Apache/nginx)
bleibt als Basis erhalten und wird um die aktuellen NVD-Treffer ergänzt (Dedup
nach CVE-ID, Schweregrad aus dem CVSS-Score abgeleitet).
# Standard: Online-Abgleich ist aktiv
python scan.py "https://example.com" --checks server
# Nur die mitgelieferte Liste (offline / kein externer Request)
python scan.py "https://example.com" --checks server --no-cve-online
# Cache erzwungen neu laden
python scan.py "https://example.com" --checks server --cve-refresh
# Weniger Rauschen: nur die 5 schwersten CVEs je Komponente
python scan.py "https://example.com" --checks server --cve-max 5
**So funktioniert's & worauf zu achten ist:**
- **Abgedeckte Komponenten:** Apache httpd, nginx, PHP, OpenSSL (jeweils sofern
Version im `Server`- bzw. `X-Powered-By`-Header sichtbar). Hinweis: Für PHP/
OpenSSL ist die NVD-Trefferliste tendenziell „lauter" (breite CPE-Bereiche) –
HIGH/CRITICAL-Funde daher besonders manuell gegenprüfen.
- **Menge begrenzen:** Pro Komponente werden standardmäßig die 25 schwersten
CVEs gemeldet. Über `--cve-max N` (CLI) bzw. das Feld *„max. CVEs/Komponente"*
in der Web-UI lässt sich das anpassen. Der Cache speichert die volle Liste, ein
geändertes Limit wirkt also sofort ohne `--cve-refresh`.
- **Datenschutz/Opsec:** An die NVD wird **ausschließlich die Produktversion**
(z.B. `apache 2.4.49` als CPE) gesendet – niemals die Ziel-URL, Cookies oder
sonstige Scan-Daten.
- **Cache:** Ergebnisse werden lokal zwischengespeichert (unter
`%LOCALAPPDATA%\web-vuln-scanner\cve\`, Standard-TTL 24 h), um die NVD-Rate-
Limits zu schonen. `--cve-refresh` umgeht den Cache.
- **Offline-sicher:** Ohne Internet, bei Timeout oder NVD-Fehler nutzt der Scan
automatisch den (ggf. älteren) Cache bzw. die mitgelieferte Liste – ein Scan
schlägt durch den CVE-Abgleich nie fehl.
- **Rate-Limit / API-Key (optional):** Ohne Key gilt das öffentliche NVD-Limit
(~5 Anfragen / 30 s), für Einzel-Scans ausreichend. Für häufige Scans einen
kostenlosen NVD-API-Key per Umgebungsvariable hinterlegen:
$env:NVD_API_KEY = "dein-key"
- **Web-UI:** Häkchen *„CVEs online abgleichen (NVD)"* (standardmäßig aktiv).
## ASVS-5.0-Report (automatisierte Prüfungen)
Mit `--asvs` (CLI) bzw. dem Häkchen **ASVS-5.0-Report** in der Web-UI erstellt der
Scanner zusätzlich einen nach Kategorien gegliederten Report entlang des **OWASP
Application Security Verification Standard 5.0**. In der Web-UI erscheint dafür ein
**eigener Tab „ASVS-Report"** neben den klassischen Befunden.
python scan.py "https://example.com/seite?id=1" --asvs
python scan.py "https://example.com" --asvs --json ergebnis.json # ASVS auch im JSON
Der Report ist in die sechs angefragten Kategorien gegliedert (mit ASVS-5.0-Kapitelbezug):
| Kategorie | ASVS-5.0-Kapitel | Automatisiert geprüft |
|-----------|------------------|------------------------|
| Architektur und Bedrohungsanalyse | V15 | security.txt, Defense-in-Depth-Header (Rest: manuell) |
| Authentifizierung | V6 | Login/Zugangsdaten nur über TLS, kein Basic-Auth ohne TLS |
| Sitzungsmanagement | V7 | Session-Cookies mit Secure/HttpOnly/SameSite |
| Zugriffskontrolle | V8 | offene sensible Dateien, Directory Listing |
| Validierung und Codierung | V1/V2/V3 | SQL-Injection, reflektiertes XSS, `nosniff`, CSP |
| Kryptographie | V11/V12 | HTTPS/TLS, Zertifikat, veraltete Protokolle, HSTS |
**Status je Anforderung:**
- **PASS** – automatisch geprüft und erfüllt
- **FAIL** – automatisch geprüft und verletzt
- **WARN** – auffällig / empfohlene Härtung fehlt
- **INFO** – neutrale Beobachtung
- **NA** – *per Blackbox nicht automatisiert prüfbar* (erfordert manuelles Review)
## Aktive Verifikation (nicht-destruktiv)
Mit `--verify` (CLI) bzw. dem Button **„Verifizieren"** an jedem Befund in der
Web-UI lässt sich ein Verdacht aktiv zu einem belastbaren Nachweis machen –
**ohne Schaden**: nur lesende bzw. eng gedeckelte Anfragen, kein Schreiben/Löschen,
keine Flutung, keine Codeausführung.
# Alle aktiv & sicher prüfbaren Befunde nach dem Scan bestätigen
python scan.py "https://example.com/seite?id=1" --verify
**Sicher verifizierbar (Button/Test vorhanden):**
| Befund | Sicherer aktiver Test |
|--------|------------------------|
| Apache Path-Traversal (CVE-2021-41773/42013) | Eine kodierte PoC-Anfrage, prüft auf `root:`-Zeile aus `/etc/passwd` (read-only) |
| SQL-Injection | Lesende Boolean-/Fehler-Reproduktion (kein Datenabzug) |
| HTTP TRACE / XST | TRACE mit Marker, prüft Rückspiegelung |
| Offene `.env`/`.git`, Directory Listing | Erneuter Abruf + Inhalts-Auszug als Beleg |
**Schutzmechanismus-Probe statt „abgeschwächtem DoS":** Für die DoS-Klasse
(z.B. HTTP/2 Rapid Reset, CVE-2023-44487) wird **kein** Flooder gebaut – auch kein
gedrosselter, denn ein Limit ist nur eine Konstante. Stattdessen misst eine
**fest gedeckelte Probe** (max. 40 normale Anfragen über ~3 s, Stopp beim ersten
Schutzsignal), **ob die Gegenseite eingreift**: `429`/`503`, `Retry-After`,
Verbindungs-Reset oder WAF/CDN-Antwort. Zusätzlich wird per ALPN geprüft, ob der
Server überhaupt HTTP/2 spricht. Das beantwortet „greift ein Schutz?", ohne ein
Angriffswerkzeug zu sein.
## Rechtlicher Compliance-Report (DE)
Mit `--legal` (CLI) bzw. dem Häkchen **„Rechtliches (DE)"** in der Web-UI erstellt der
Scanner einen nach Kategorien gegliederten Report (eigener Tab) mit Fokus auf deutsches
Recht – rein lesend:
- **Impressum** (§5 DDG/TMG): Link/Seite vorhanden? Pflichtangaben (Anschrift, Kontakt) erkennbar?
- **Datenschutz/DSGVO** (Art. 13): Datenschutzerklärung vorhanden + DSGVO-typische Inhalte?
- **Cookies & Tracking** (TTDSG/DSGVO): **Google Fonts von Google** (IP-Transfer USA, LG München I),
Google Analytics/Tag Manager, Facebook Pixel, reCAPTCHA; Consent-Tool erkannt? Nicht-essentielle
Cookies vor Einwilligung?
- **AGB / Verbraucher**: AGB verlinkt?
- **SEO**: Title/Meta-Description, genau eine H1, Canonical, Viewport, Open Graph, JSON-LD,
robots.txt, sitemap.xml.
- **Barrierefreiheit** (WCAG/BITV/**BFSG ab 28.06.2025**): **detaillierte WCAG-2.2-Prüfung (A/AA)**
Erfolgskriterium für Erfolgskriterium – u. a. 1.1.1 (alt), 1.3.1 (Labels/Tabellen), 1.3.5
(autocomplete), 1.4.3 (Inline-Kontrast), 1.4.4 (Zoom nicht blockiert), 2.1.1 (tabindex),
2.4.1 (Skip/Landmarks), 2.4.2 (Titel), 2.4.4 (Linktexte), 2.4.6 (Überschriften), 3.1.1 (lang),
3.3.8 (CAPTCHA, neu in 2.2), 4.1.2 (Name/Rolle/Wert, ARIA-Referenzen) sowie
**Screenreader-/ARIA-Regeln** (aria-hidden auf Fokussierbarem, erforderliche ARIA-States,
Landmark-Eindeutigkeit, abstrakte Rollen). **Kontrast** wird aus **Inline-Styles, `