CDP 35948520/Checkliste General: 35 Web App Security Checks #31
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Quelle
samples/CDP/checklists/general.xlsxCheckliste (35 Checks)
Phase: Build
Authentication
✅ TOTP MFA implementiert (
MfaSetup.tsx), Setup via QR-Code.✅ Login-Formular hat kein Prefill durch Server-State.
✅ Argon2id mit automatischem Salt (
@node-rs/argon2), Work-Factor Default.✅ Token-basierter Reset-Flow (
/auth/reset-password/[token]), kein Cleartext.✅ Dev-Seed nutzt Argon2id Hashes, Admin-Setup via CLI (
scripts/setup-admin.mjs).✅ Secrets nur in ENV-Variablen (
.env), nie commited.⚪ Keine Security-Fragen im Einsatz.
🔴 TODO: Password-Blacklist-Check (z. B.
haveibeenpwnedAPI oderzxcvbn) ergänzen.✅
.envin.gitignore,.env.examplemit Platzhaltern. CI-Scan via Dependabot.✅ Argon2id (OWASP-empfohlen, stärker als SHA512crypt).
✅ Auth.js Credentials-Provider via POST-Form, keine Basic-Auth.
✅ Login ist normale Next.js-Seite
/auth/signin, kein Popup.✅
type="password"auf allen Password-Inputs (signin/page.tsx:174).✅ Generic message
"Invalid email or password"(signin/page.tsx:55).✅ Per-Email-Lockout implementiert (
apps/web/src/server/auth.ts:52-68): 5 Fehlversuche / 15 Min →Too many login attempts+ Audit-Log. 15-Min-Fenster verhindert DoS. Erfüllt Intent.✅ Login-Formular hat kein Remember-Me-Feld (
signin/page.tsx).✅
autoComplete="current-password"gesetzt (signin/page.tsx:180). Hinweis: Accenture-Originaltextautocomplete=OFFist überholt — moderne Guidance (OWASP ASVS v4 2.7.3) empfiehltcurrent-passwordfür Password-Manager-Integration.🔴 TODO: Kein Password-Expiry implementiert. Falls gefordert:
User.passwordChangedAt+ Expiry-Check in Auth-Callback.🟡 Gitea-PATs werden manuell rotiert. TODO: Rotations-Prozess dokumentieren.
Ownership
✅ Ja — Gitea self-hosted.
✅ Self-managed für interne Nutzung (keine Accenture/Client-Ownership im klassischen Sinn — projektintern).
Platform
✅ Gitea (https://gitea.io/).
✅
https://gitea.hartmut-noerenberg.com.🟡 Repo liegt auf öffentlich erreichbarer Domain, aber mit Login-Wall (Gitea-Auth). TODO: IP-Whitelisting oder VPN-Only-Zugang evaluieren.
Phase: Test
Authentication
✅ nginx Reverse Proxy mit TLS1.2+ (siehe
docs/nginx-hardening.conf).✅ Siehe Build-Check oben.
✅
apps/web/src/middleware.tsblockt unauthenticated Access, Prisma/Zod verhindern Injection.✅ Kein Remember-Me-Feld.
✅
Cache-Control: no-storeauf Auth-Seiten + API (next.config.ts).🟡 Länge ≥ 12 via Zod (
auth.ts:77), kein Complexity/Reuse/Aging-Check. TODO: Policy erweitern (siehedocs/security-audit-2026-03-15.md:294).⚪ Keine Security-Fragen im Einsatz.
✅ Token-basierter Flow, CSRF-Schutz via Auth.js + SameSite=Strict.
🟡 TOTP MFA verfügbar, aber aktuell optional. TODO: MFA-Enforcement für Admin-Rollen + sensitive Transaktionen.
✅ Middleware (
apps/web/src/middleware.ts) schützt alle Routen außer explizit public.✅ Max 3 Sessions pro User, älteste wird gekickt (siehe Compliance-Doc EAPPS 3.2.2.4.02).
Review-Ergebnis
Detail-Analyse aller 35 Checks aus
samples/CDP/checklists/general.xlsxgegen CapaKraken-Code unddocs/acn-security-compliance-status.md.🔴 Offene Gaps — Aktion erforderlich
haveibeenpwnedAPI oderzxcvbn) ergänzen.docs/security-audit-2026-03-15.md:158). Aktuell nur globales Rate-Limit5/15minauf/auth.autocompleteAttribut auf Email/Password-Inputs insignin/page.tsxergänzen (empfohlen:autocomplete="username"/"current-password").User.passwordChangedAt+ Expiry-Check in Auth-Callback.🟡 Partials — Follow-up sinnvoll
auth.ts:77), kein Complexity/Reuse/Aging-Check. TODO: Policy erweitern (siehedocs/security-audit-2026-03-15.md:294).Empfehlung:
4 Gap(s) schließen, 4 Partial(s) als Follow-up. Danach Ticket schließen.
Korrektur nach Code-Review
Zwei als 🔴 markierte Checks sind tatsächlich bereits implementiert und wurden auf ✅ korrigiert:
apps/web/src/server/auth.ts:52-68implementiert Per-Email-Lockout mit 5 Fehlversuchen / 15 Min, inkl. Audit-Log für geblockte Versuche. Das 15-Min-Fenster schützt gegen DoS (fehlversuchende Angreifer können nicht dauerhaft sperren).apps/web/src/app/auth/signin/page.tsx:180setztautoComplete="current-password". Der ursprüngliche Accenture-Textautocomplete=OFFist überholt; moderne OWASP-ASVS-Guidance (4.0.3, V2.7.3) empfiehlt explizitcurrent-passwordfür Password-Manager-Kompatibilität.Verbleibende echte Gaps (2)
User.passwordChangedAt+ Rotation-Prompt noch offen.Verbleibende Partials (4)
min(12), keine Complexity/History.Aktueller Stand: 28 ✅ OK / 4 🟡 PARTIAL / 2 🔴 GAP / 3 ⚪ N/A (von 37 Checks).