# QA-04 — Sicherheits- & Berechtigungsprüfung: Prüfprotokoll Datum: 2026-09-01 Host: 192.168.1.131 (Build/Test/Lint), rsync + ssh Geprüfte Pakete: `mail/internal/smtp`, `mail/internal/mailer`, `mail/internal/storage`, `mail/internal/folderstate`, `mail/internal/mailboxconfig`, `mail/internal/ratelimit` ## Umsetzung — echter Sicherheitsbefund und Korrektur Der gezielte Testangriff auf den SMTP-Pfad (Pflichtprüfung 1) deckte einen REALEN Härtungsfehler auf, der VOR dieser Kachel unbemerkt geblieben war: ING-07 (Idle-Timeout-Schutz) hatte `protoguard` nur in `mail/internal/imap` und `mail/internal/pop3` verdrahtet — `mail/ internal/smtp` bekam versehentlich NIE einen Idle-Timeout. Eine Gegenstelle, die eine Kommandozeile ohne abschließendes CRLF öffnet und nie beendet, konnte die Session unbegrenzt blockieren (bestätigt durch `TestQA04_OversizedLineWithoutCRLFDoesNotHangOrCrash`, VOR der Korrektur real reproduziert: Server antwortete nach 8s Wartezeit weder mit Fehler noch Verbindungsende). **Korrektur** (`session.go`/`server.go`, `mail/internal/smtp`): `guard *protoguard.Guard` als neues Feld, Idle-Timeout wird jetzt in `readLine()` selbst gesetzt — EIN Ort für alle Aufrufer (Haupt-Serve- Schleife, `handleData`, `drainUntilDot`), damit auch das Lesen des DATA-Bodys geschützt ist. Neuer Konstruktor `NewServerWithMaxMessageBytesTLSLoggerRateLimitAndGuardConfig` für abweichende Timeout-Werte (Tests). Bestehende Konstruktoren bekommen automatisch `protoguard.DefaultConfig()` (5 Minuten) statt wie zuvor gar keinen Timeout — reine Härtung, keine Verhaltensänderung für funktionierende Clients. ## Pflichtprüfung 1: Gezielter Testangriff auf Header-Injection schlägt fehl `TestQA04_HeaderInjectionViaEnvelopeAddressRejected` (`smtp/qa04_security_test.go`): NUL-Byte und Steuerzeichen in RCPT TO/MAIL FROM werden mit `553`/`501` zurückgewiesen, Session bleibt danach funktionsfähig, keine Nachricht erreicht den Sink. Ergänzt um `TestQA04_OversizedLineWithoutCRLFDoesNotHangOrCrash` (Ressourcen- erschöpfungsangriff, siehe Abschnitt "Umsetzung" — deckte den realen Härtungsfehler auf und bestätigt nach der Korrektur zuverlässige Reaktion binnen des konfigurierten Timeouts). Bereits bestehende, unverändert gültige Nachweise aus ING-03/ING-06 werden mitgezählt: CRLF-Injection in Betreff/Anzeigename (`mailer.TestHeaderWriter_ RejectsControlCharsAndCRLFInSubjectAndDisplayName`), Dot-Stuffing korrekt gegen DATA-Command-Smuggling (`smtp.TestData_ MessageSizeCheckedBeforeAcceptance` u. a.), TLS-Downgrade-Angriffe (`smtp.TestServer_RejectsLegacyTLSVersionAndWeakCiphers`, ING-06). Ergebnis: **BESTANDEN** — inklusive eines real gefundenen und behobenen Härtungsfehlers. ## Pflichtprüfung 2: Stichprobenprüfung mehrerer Speicherpfade auf Mandantentrennung Drei unabhängige Speicherpfade stichprobenartig geprüft: 1. **Objekt-Storage** (`mail/internal/storage`, ARC-06): physische Bucket-Trennung, bereits real gegen MinIO nachgewiesen (`TestProvisionTenant_CreatesPhysicallySeparateBuckets`, `TestAccessWithoutTenantContext_FailsBecauseNoBucketReferenceable` — siehe `ARC-06-PRUEFPROTOKOLL.md`). 2. **Folder-State** (`mail/internal/folderstate`, ING-10): `NextUID`/`Rebuild` für Mandant A verändern Mandant Bs Zustand nachweislich nicht (`TestTenantScoping_ NeverReturnsOrMutatesOtherTenantsFolderState`). 3. **Postfachkonfiguration** (`mail/internal/mailboxconfig`) — NEU für diese Kachel, bislang nicht auditiert, besonders sensibel (verschlüsselte IMAP-Zugangsdaten): `TestTenantScoping_ ForeignKnownIDNeverAccessible` — Mandant B versucht mit einer ECHTEN, bekannten ID aus Mandant As Zeile (realistischster Angriffsfall bei fortlaufenden IDs in einer gemeinsamen Tabelle) auf `List`/`GetDecryptedPassword`/`Update`/`Delete` zuzugreifen — jeder Versuch liefert `ErrNotFound`, Mandant As Daten bleiben unverändert. Ergebnis: **BESTANDEN** in allen drei gezogenen Stichproben. ## Pflichtprüfung 3: Test: API-Zugriff mit widerrufenem/fremdem Token wird verweigert **Teilweise nicht durchführbar, dokumentiert:** Das Mail-Modul besitzt aktuell KEINE eigene HTTP-API mit Token-/Session-Authentifizierung — jede vorhandene Schnittstelle (`web/mail-search`, SRC-04) verweist explizit auf eine noch ausstehende "zentrale Session-/IAM-Anbindung (Core-Board-Scope, nicht Bestandteil dieser Kachel)", konsistent mit QA-04s eigener Ausgangslage: "Berührt Login-Tenant-Filter und Privilege-Escalation – dafür ist bereits Core-Board IAM zuständig, hier nur Mail-spezifische Aspekte prüfen." Es gibt daher keinen Prüfgegenstand für "widerrufenes/fremdes API-Token" innerhalb des Mail-Boards — dieser Teil bleibt **offen**, bis Core-Board IAM eine Token-Schnittstelle liefert, gegen die geprüft werden kann. Der **Rate-Limiting-Teil** von Akzeptanzkriterium 3 ist dagegen real vorhanden und geprüft (ING-09): `TestRateLimit_ LoadExceedingLimitGetsRejectedWithRetryHint`, `TestRateLimit_LegitUsageBelowThresholdUnaffected`, `TestRateLimit_PerTenantIndependentAndEffective` — je einmal in IMAP, POP3, SMTP, alle mit echten Nachweisen bestanden (siehe `ING-09-PRUEFPROTOKOLL.md`), hier erneut mitgeprüft und bestätigt grün. Ergebnis: **Rate-Limiting-Teil BESTANDEN, API-Token-Teil OFFEN** (kein Prüfgegenstand im Mail-Board vorhanden). ## Akzeptanzkriterien 1. **Prüfung bestätigt wirksame Härtung des SMTP-Pfads gegen bekannte Angriffsmuster**: durch Pflichtprüfung 1 belegt — inklusive eines real gefundenen und in dieser Kachel behobenen Härtungsfehlers (fehlender Idle-Timeout). 2. **Prüfung bestätigt lückenlose Mandantentrennung im Speicherpfad**: durch Pflichtprüfung 2 belegt (drei Speicherpfade, keine Lücke gefunden). 3. **Prüfung bestätigt korrekt greifendes API-Token-/Rate-Limiting**: Rate-Limiting-Teil durch Pflichtprüfung 3 belegt; API-Token-Teil bleibt offen (kein Prüfgegenstand, siehe oben). ## Build/Vet/Lint/Test — Gesamtmodul ``` go build ./... → OK go vet ./... → OK golangci-lint run ./... → 0 issues go test ./... -p 1 (TEST_TENANT_DSN, TEST_MANTICORE_URL, TEST_S3_ENDPOINT/TEST_S3_ACCESS_KEY/TEST_S3_SECRET_KEY gesetzt) → alle Pakete ok ``` Keine Regression — insbesondere QA-07-Lasttest für SMTP bleibt nach der Idle-Timeout-Korrektur unverändert grün (6057,8 Sessions/s, p95 48,2ms). ## Ergebnis QA-04 erfüllt Akzeptanzkriterium 1 und 2 vollständig mit echten, ausgeführten Nachweisen — inklusive eines real gefundenen und behobenen Sicherheitsfehlers (fehlender SMTP-Idle-Timeout). Akzeptanzkriterium 3 ist zur Hälfte (Rate-Limiting) erfüllt; die API-Token-Hälfte bleibt offen, da im Mail-Board kein Prüfgegenstand existiert (bewusst an Core-Board IAM delegiert, siehe QA-04s eigene Ausgangslage). Board wird auf Basis der erfüllbaren Teile fortgeführt, das offene Element ist hier und im Entscheidungsverlauf vermerkt. Freigeschaltet: QA-09.