IMP-10: pruefprotokoll
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Mail-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Mail-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
eb63746bbc
commit
3cce9c1107
1 file changed
+40
@@ -0,0 +1,40 @@
|
||||
# IMP-10 – Prüfprotokoll: IMAP-Import mit TLS und sicheren Befehlen
|
||||
|
||||
Ticket: `mail-kanban/tickets/IMP-10.md`. Basis: `integration/gesamtprojekt` (Head 27d3dca), Branch `feature/imp-10-imap-tls-sichere-befehle-mail`.
|
||||
|
||||
## Befund
|
||||
|
||||
`mail/internal/imapimport/client_real.go` (`RealClient.Sync`) verband ohne TLS und baute `LOGIN`/`SELECT` durch reine String-Verkettung aus Benutzername, Passwort und Postfachname — QA-15-Befund F-19 (mittel, latent, da das Modul noch nicht verdrahtet ist).
|
||||
|
||||
## Umsetzung
|
||||
|
||||
- **TLS-Pflicht (AK1):** `Sync` sendet vor `LOGIN` immer `STARTTLS` und führt den TLS-Handshake durch (`crypto/tls`, `MinVersion: TLS 1.2`), außer der ausdrückliche Schalter `WithInsecureAllowPlaintextForTests()` ist gesetzt. Bietet der Server kein STARTTLS an oder lehnt es ab, bricht `Sync` mit Fehler ab, bevor Zugangsdaten gesendet werden. `WithTLSConfig` erlaubt das Setzen einer eigenen `tls.Config` (Produktivbetrieb: Systemwurzeln + aus `addr` abgeleiteter Servername; Tests: `InsecureSkipVerify` gegen das selbstsignierte Testzertifikat).
|
||||
- **Sichere Befehlskonstruktion (AK2/AK3):** Neue Funktion `quoteIMAPString` baut RFC-3501-Quoted-Strings (Escaping von `"` und `\`) und weist Werte mit `\r`, `\n` oder NUL zurück, statt sie zu escapen — eingebettet in einen Quoted-String würden sie die zeilenbasierte Übertragung ohnehin vorzeitig beenden und einen zweiten, eingeschleusten Befehl ermöglichen. `buildLoginCommand`/`buildSelectCommand` nutzen das für Benutzername, Passwort und Postfachname; ein ungültiges Passwort erzeugt bewusst einen Fehlertext ohne den Rohwert (Prüfung 2).
|
||||
- Nach dem STARTTLS-Handshake wird der gepufferte Reader neu aufgesetzt (gleiches Muster wie serverseitig in `mail/internal/imap.handleStartTLS`), damit vor dem Handshake gepufferte Klartextdaten nicht als Serverantwort nach dem Wechsel verarbeitet werden.
|
||||
|
||||
## Prüfungen (alle real auf Host 204, `go test ./internal/imapimport/...`)
|
||||
|
||||
| # | Prüfung | Ergebnis |
|
||||
|---|---|---|
|
||||
| 1 | Tests gegen den In-Process-IMAP-Server (`TestRunOnce_AgainstRealTestMailboxWithRealisticVolume`, jetzt mit STARTTLS-Aufwertung gegen selbstsigniertes Testzertifikat) | bestanden, 30/30 Nachrichten, zweiter Lauf 0 neue |
|
||||
| 1 (Negativ) | `TestSync_RejectsServerWithoutTLSOffer`: Server ohne TLS-Konfiguration wird abgelehnt | bestanden |
|
||||
| 1 (Schalter) | `TestSync_WithInsecureAllowPlaintextForTests_WorksAgainstPlaintextServer`: expliziter Test-Schalter funktioniert weiterhin | bestanden |
|
||||
| 3 | `TestSync_RejectsCRLFInjectionInUsernameAndMailbox`: `\r\n`-Einschleusung in Benutzername und Postfachname erreicht keinen zweiten Befehl, `Sync` bricht vor dem Senden mit Validierungsfehler ab | bestanden |
|
||||
| 2 | `TestSync_PasswordNeverAppearsInErrorOrLog`: Passwort erscheint bei Anmeldefehler weder im Fehlertext noch in protokollierten Meldungen | bestanden |
|
||||
| 3 | Verdrahtung des Importmoduls bleibt unverändert nicht angeschlossen (dieses Ticket ändert nur `client_real.go`, keine Aufrufstelle außerhalb der Tests existiert) | bestätigt (`grep -rn NewRealClient` außerhalb der Tests: keine Treffer) |
|
||||
|
||||
Bestandstests `nonconformant_test.go` (UIDVALIDITY=0-Fallback, kaputte FETCH-Zeilen) laufen gegen einen handgeschriebenen Fake-Server ohne STARTTLS-Verständnis; sie wurden auf den expliziten `WithInsecureAllowPlaintextForTests()`-Schalter umgestellt, da sie eine andere Schicht (Protokoll-Fehlertoleranz) prüfen, nicht TLS.
|
||||
|
||||
## Regression
|
||||
|
||||
- `go build ./...`, `go vet ./...`: sauber.
|
||||
- `gofmt -l internal/imapimport/`: leer (die vier von `gofmt -l .` gemeldeten Dateien im Gesamtmodul sind Bestand, von diesem Branch nicht berührt).
|
||||
- `go test -count=1 ./...` über das gesamte Mail-Modul: 0 FAIL.
|
||||
|
||||
## QA und Entscheidungen
|
||||
|
||||
- **Implicit-TLS-Port:** Nicht umgesetzt, nur STARTTLS-Aufwertung. Begründung: Der Testserver und alle im Repo bekannten Zielserver bieten STARTTLS auf dem Standardport, ein separater Implicit-TLS-Port wäre unbelegte Mehrarbeit außerhalb des Ticket-Scopes.
|
||||
- **CR/LF: Abweisen statt Escapen.** Ein IMAP-Quoted-String kann `\r`/`\n` nicht sicher transportieren, weil sowohl Server als auch Client zeilenbasiert lesen (`bufio.Reader.ReadString('\n')`) — ein eingebettetes `\n` würde die Zeile unabhängig von Anführungszeichen vorzeitig beenden. Abweisen ist die einzige korrekte Lösung, kein Kompromiss.
|
||||
- **Kein Merge, kein Deploy**, wie in allen Tickets dieser Session.
|
||||
|
||||
Iterationen: 1 (STARTTLS-Unwissenheit des `nonconformant_test.go`-Fakes, sofort erkannt und korrigiert).
|
||||
Reference in new issue
Block a user