ASVS-light – Checkliste für eigene Apps
Angelehnt an OWASP ASVS, reduziert auf das, was bei kleinen selbst gebauten Apps (FastAPI,
Express, React/Next) regelmäßig schiefgeht. Jeder Punkt ist prüfbar. Spalte „Beleg“ sagt,
womit man ihn nachweist.
Prioritäten: K = Kritisch (No-Go, wenn offen), H = Hoch, M = Mittel.
1. Authentifizierung
| ID |
Prio |
Punkt |
Beleg |
| A1 |
K |
Jede Route außer einer expliziten Public-Liste verlangt Login |
Test „jede Route verlangt Auth“ (Routen aus OpenAPI/Router, Leerlauf-Sperre) |
| A2 |
K |
Identität kommt aus geprüfter Quelle (Session, JWT mit Signaturprüfung, Proxy-Header nur mit Shared Secret) |
Spoofing-Test: gefälschter Header ohne Secret → 401 |
| A3 |
K |
App-Port ist nicht am Reverse-Proxy vorbei erreichbar (Compose: kein ports: oder nur 127.0.0.1:) |
docker compose config, ss -tlnp, Zugriff von anderem Host |
| A4 |
H |
Session-Cookies: HttpOnly, Secure, SameSite=Lax/Strict |
Test auf Set-Cookie |
| A5 |
H |
Login/Token-Endpunkte haben Rate-Limit |
Konfiguration + Test |
| A6 |
M |
Logout invalidiert die Session serverseitig |
Test |
2. Autorisierung
| ID |
Prio |
Punkt |
Beleg |
| B1 |
K |
Objektzugriff wird pro Objekt geprüft (kein IDOR): Nutzer B kann Objekt von A weder lesen noch ändern noch löschen |
IDOR-Tests mit zwei Nutzern |
| B2 |
K |
Listen-Endpunkte liefern nur erlaubte Objekte |
Test: Liste von B enthält nichts von A |
| B3 |
H |
Rollenmatrix ist dokumentiert und als Tests abgebildet |
Skill authz-idor-audit |
| B4 |
H |
Rechte werden serverseitig geprüft, nicht nur im UI versteckt |
Test direkt gegen API |
| B5 |
M |
Admin-Funktionen auf eigenen Routen mit eigener Prüfung |
Code-Review |
3. Eingaben
| ID |
Prio |
Punkt |
Beleg |
| C1 |
K |
SQL ausschließlich parametrisiert / ORM, keine String-Verkettung |
Semgrep-Regeln, Ruff S608 |
| C2 |
H |
Alle Request-Bodies laufen durch Schemas mit „unbekannte Felder verboten“ (Pydantic extra="forbid", zod .strict()) |
Mass-Assignment-Test (role, owner, leader im Body → 422/400) |
| C3 |
H |
Ungültige Eingaben → 4xx, nie 500 |
Test ungültige Eingabe, Fuzzing (make fuzz) |
| C4 |
H |
Kein eval/exec, kein shell=True, kein unsicheres Deserialisieren (pickle, yaml.load) |
Semgrep, Bandit |
| C5 |
M |
Datei-Uploads: Typ/Größe begrenzt, Pfad nicht vom Client bestimmt |
Test |
4. Frontend
| ID |
Prio |
Punkt |
Beleg |
| D1 |
H |
Kein dangerouslySetInnerHTML/innerHTML mit nicht vertrauenswürdigen Daten |
ESLint react/no-danger, Semgrep |
| D2 |
H |
Keine Tokens/Secrets in localStorage/sessionStorage |
Semgrep, Playwright-Test auf Web Storage |
| D3 |
M |
Security-Header gesetzt (CSP, X-Content-Type-Options, frame-ancestors) |
ZAP-Baseline (make zap) |
| D4 |
M |
Keine Secrets im Frontend-Bundle (NEXT_PUBLIC_*, VITE_* prüfen) |
gitleaks auf Build-Output |
5. Konfiguration
| ID |
Prio |
Punkt |
Beleg |
| E1 |
K |
Keine Secrets im Repo oder in der Git-Historie |
gitleaks (Pre-Commit + CI) |
| E2 |
K |
CORS: kein *, kein origin: true zusammen mit Credentials |
CORS-Test, Semgrep |
| E3 |
H |
Debug-Modus aus, API-Docs in Prod aus oder geschützt |
Prod-Konfigurationstest |
| E4 |
H |
Fehlerantworten ohne Stacktrace/Exception-Text |
Test auf generische 500er |
| E5 |
H |
TLS-Prüfung nie abgeschaltet (verify=False, rejectUnauthorized:false, NODE_TLS_REJECT_UNAUTHORIZED=0) |
Semgrep |
| E6 |
M |
Container läuft nicht als root, Image ohne High/Critical |
make container (Trivy, hadolint) |
6. Abhängigkeiten
| ID |
Prio |
Punkt |
Beleg |
| F1 |
K |
Keine High/Critical-Lücken ohne dokumentierte Ausnahme |
make audit |
| F2 |
H |
Jede neue Dependency vorher geprüft (existiert, nicht typosquat, gepflegt) |
Skill dependency-vetting, make vet-deps |
| F3 |
M |
Lockfile im Repo (package-lock.json, requirements*.txt gepinnt) |
Repo |
7. Datenschutz
| ID |
Prio |
Punkt |
Beleg |
| G1 |
H |
Gesundheitsdaten (z. B. Abwesenheitsgrund „krank“) nur speichern, wenn nötig; sonst neutrale Abwesenheit |
Datenmodell |
| G2 |
H |
Logs ohne personenbezogene Daten, Tokens, Passwörter |
Code-Review, Log-Stichprobe |
| G3 |
M |
Testdaten synthetisch, keine echten Mitarbeiter-/Kundendaten in Tests, Fixtures, Seeds |
Review |
| G4 |
M |
Löschkonzept: wer löscht wann welche Personendaten |
Doku |