Sicherheit: Mögliche Konten-Aufdeckung bei SMTP-Fehlern im Passwort-Reset #37

Closed
opened 2026-11-03 09:02:04 +00:00 by cschlaefke · 1 comment
Owner

Kontext

Aus dem Review von PR #36 (KTO-01, 01c). Refs #1.

Problem (Verdacht, nicht nachgewiesen)

GoTrue liefert bei POST /recover für unbekannte Adressen immer 200. Für bestehende Adressen wird tatsächlich eine Mail versendet. Schlägt der Versand fehl (SMTP-Ausfall, SMTP-Fehler), könnte GoTrue für bestehende Adressen einen Fehler (z. B. 500) liefern, für unbekannte aber weiterhin 200.

Der ForgotPasswordController behandelt nur over_email_send_rate_limit (emailSendLimited, F12) wie Erfolg. Alle anderen Fehler laufen in den default-Zweig und zeigen ein Fehler-Banner. Dann wäre am Banner erkennbar, ob ein Konto zu der Adresse existiert (Konten-Enumeration). Dasselbe Muster ist beim signUp als Restrisiko „SMTP-Ausfall“ bekannt (Spec, Risiken).

Zu klären

  • Spike: Verhalten von GoTrue (v2.197.0) bei recover und signup mit nicht erreichbarem/fehlerhaftem SMTP (Mailpit abschalten), jeweils bekannte vs. unbekannte Adresse: Statuscode und Body vergleichen.
  • Wenn Unterschied vorhanden: Entscheidung (Chris), z. B.
    • Client zeigt bei allen Nicht-Eingabefehlern der Recovery-/Signup-Anfrage (außer reinem Offline/429 der Anfrage selbst) die neutrale CheckEmail-Seite, oder
    • Fehler serverseitig vereinheitlichen (Gateway/Edge Function), oder
    • Risiko dokumentieren und akzeptieren.
  • Abwägung Nutzbarkeit: Nutzer bekommt bei echtem SMTP-Ausfall keine Mail und keinen Hinweis.
  • Umsetzung + Tests (Controller-, Widget-Test mit exaktem Textvergleich für bekannte/unbekannte Adresse bei SMTP-Fehler), Eintrag in Spec/Risiken und docs/auth-konfiguration.md.

Betroffen

app/lib/features/auth/presentation/forgot_password/forgot_password_controller.dart (Fall default), register_controller.dart, auth_failure_mapper.dart; ggf. Gateway/Betrieb (D1).

Priorität

Sicherheitsrelevant (Enumeration-Schutz, KTO-01 Krit. 4). Vor dem Produktiv-Release zu klären.

## Kontext Aus dem Review von PR #36 (KTO-01, 01c). Refs #1. ## Problem (Verdacht, nicht nachgewiesen) GoTrue liefert bei `POST /recover` für **unbekannte** Adressen immer 200. Für **bestehende** Adressen wird tatsächlich eine Mail versendet. Schlägt der Versand fehl (SMTP-Ausfall, SMTP-Fehler), könnte GoTrue für bestehende Adressen einen Fehler (z. B. 500) liefern, für unbekannte aber weiterhin 200. Der `ForgotPasswordController` behandelt nur `over_email_send_rate_limit` (`emailSendLimited`, F12) wie Erfolg. Alle anderen Fehler laufen in den `default`-Zweig und zeigen ein Fehler-Banner. Dann wäre am Banner erkennbar, **ob ein Konto zu der Adresse existiert** (Konten-Enumeration). Dasselbe Muster ist beim `signUp` als Restrisiko „SMTP-Ausfall“ bekannt (Spec, Risiken). ## Zu klären - [ ] Spike: Verhalten von GoTrue (v2.197.0) bei `recover` und `signup` mit nicht erreichbarem/fehlerhaftem SMTP (Mailpit abschalten), jeweils bekannte vs. unbekannte Adresse: Statuscode und Body vergleichen. - [ ] Wenn Unterschied vorhanden: Entscheidung (Chris), z. B. - Client zeigt bei **allen** Nicht-Eingabefehlern der Recovery-/Signup-Anfrage (außer reinem Offline/429 der Anfrage selbst) die neutrale CheckEmail-Seite, oder - Fehler serverseitig vereinheitlichen (Gateway/Edge Function), oder - Risiko dokumentieren und akzeptieren. - [ ] Abwägung Nutzbarkeit: Nutzer bekommt bei echtem SMTP-Ausfall keine Mail und keinen Hinweis. - [ ] Umsetzung + Tests (Controller-, Widget-Test mit exaktem Textvergleich für bekannte/unbekannte Adresse bei SMTP-Fehler), Eintrag in Spec/Risiken und `docs/auth-konfiguration.md`. ## Betroffen `app/lib/features/auth/presentation/forgot_password/forgot_password_controller.dart` (Fall `default`), `register_controller.dart`, `auth_failure_mapper.dart`; ggf. Gateway/Betrieb (D1). ## Priorität Sicherheitsrelevant (Enumeration-Schutz, KTO-01 Krit. 4). Vor dem Produktiv-Release zu klären.
cschlaefke added the
type/bug
prio/must
needs-clarification
labels 2026-11-03 09:02:04 +00:00
Author
Owner

Spike-Ergebnis (aus #38, GoTrue v2.197.0, SMTP-Port lehnt Verbindung ab)

Das Risiko ist bestätigt: Bei SMTP-Ausfall verrät die rohe API die Existenz eines Kontos. Antworten kamen jeweils in unter 60 ms, ein Zeit-Seitenkanal besteht nicht.

Aufruf bekannte Adresse unbekannte Adresse
/recover 500 unexpected_failure 200
/resend unbestätigt: 500 200
/signup unbestätigt: 500, bestätigt: 200 neu: 500 (Nutzer wird zurückgerollt)

Folgerung: Die App zeigt im Fall default ein Fehler-Banner, dadurch ist bei „Passwort vergessen“ und beim erneuten Senden erkennbar, ob ein Konto existiert. Bei der Registrierung kehrt sich das Muster um (neue Adresse = 500, bestätigte = 200).

Offen: SMTP-Server, der die Verbindung annimmt, aber nicht antwortet (Timeout), z. B. GOTRUE_SMTP_HOST=10.255.255.1. Siehe docs/auth-konfiguration.md Abschnitt 7 (auf Branch feature/38-auth-e2e).

Entscheidung nötig (Chris): Option 1: Client zeigt bei jedem Nicht-Eingabefehler dieser Aufrufe die neutrale CheckEmail-Seite (Nutzer erfährt bei echtem SMTP-Ausfall nichts, Monitoring nötig). Option 2: Vereinheitlichen am Gateway. Option 3: Risiko akzeptieren und dokumentieren.

## Spike-Ergebnis (aus #38, GoTrue v2.197.0, SMTP-Port lehnt Verbindung ab) Das Risiko ist **bestätigt**: Bei SMTP-Ausfall verrät die rohe API die Existenz eines Kontos. Antworten kamen jeweils in unter 60 ms, ein Zeit-Seitenkanal besteht nicht. | Aufruf | bekannte Adresse | unbekannte Adresse | |---|---|---| | `/recover` | **500** `unexpected_failure` | **200** | | `/resend` | unbestätigt: **500** | **200** | | `/signup` | unbestätigt: **500**, bestätigt: **200** | neu: **500** (Nutzer wird zurückgerollt) | **Folgerung:** Die App zeigt im Fall `default` ein Fehler-Banner, dadurch ist bei „Passwort vergessen“ und beim erneuten Senden erkennbar, ob ein Konto existiert. Bei der Registrierung kehrt sich das Muster um (neue Adresse = 500, bestätigte = 200). **Offen:** SMTP-Server, der die Verbindung annimmt, aber nicht antwortet (Timeout), z. B. `GOTRUE_SMTP_HOST=10.255.255.1`. Siehe `docs/auth-konfiguration.md` Abschnitt 7 (auf Branch `feature/38-auth-e2e`). **Entscheidung nötig (Chris):** Option 1: Client zeigt bei jedem Nicht-Eingabefehler dieser Aufrufe die neutrale CheckEmail-Seite (Nutzer erfährt bei echtem SMTP-Ausfall nichts, Monitoring nötig). Option 2: Vereinheitlichen am Gateway. Option 3: Risiko akzeptieren und dokumentieren.
Sign in to join this conversation.
No description provided.