Manticore-RT-Index für Mail-Suchdokumente (Betreff, Text, Anhangstext, Metadaten), statisches versioniertes Schema. - fields.go: statische Feld-/Index-Namen-Whitelist, einzige Quelle für Feldnamen im Paket (vermeidet known-issues-archivmail.md #11/#12: Sprintf/Join-basierte SQL-Klauselbildung). - migrations/0001_mail_documents.sql: statisches Schema, per go:embed eingebettet, über /sql?mode=raw angelegt (kein String-Zusammenbau). - client.go: Index/Search über die strukturierte Manticore-HTTP-JSON-API, Tenant-Filter über strukturiertes equals-Feld statt WHERE-Interpolation. Prüfungen (alle real durchgeführt, siehe mail/docs/SRC-01-PRUEFPROTOKOLL.md): 1. TestNoDynamicSQLClauseBuilding: automatisierter Quelltext-Scan bestätigt keine Sprintf/Join-SQL-Klauselbildung. 2. TestSearch_MaliciousInputDoesNotAlterFieldNames: Injection-artige Eingaben verändern nachweislich keine Feldnamen im gesendeten Payload. 3. TestSearch_FindsExpectedDocument: Funktionstest gegen echtes Manticore auf 192.168.1.131 liefert erwartete Treffer. Zusätzlich TestSearch_TenantIsolation für Akzeptanzkriterium 3. Kein Umbau: storage/crypto/encstorage/dedup unverändert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
3.6 KiB
3.6 KiB
SRC-01 – Prüfprotokoll: Manticore-Suchindex für Mails
Voraussetzung ARC-01, ARC-03 (beide Fertig).
Umsetzung
mail/internal/search/fields.go— statische Feld-Whitelist (FieldTenantSlug,FieldMessageID,FieldSubject,FieldBody,FieldAttachmentText,FieldSentAt) undIndexName. Bekannten Fehler vermeiden (known-issues-archivmail.md #11/#12): archivmail baute WHERE-Klauseln und teils Spalten-/Tabellennamen dynamisch überfmt.Sprintf/strings.Join. Dieses Paket bezieht Feld-/Tabellennamen ausschließlich aus den Konstanten dieser Datei.mail/internal/search/migrations/0001_mail_documents.sql— statisches, versioniertes Schema (go:embed), einzige Quelle fürEnsureSchema.mail/internal/search/client.go—Client:EnsureSchemalegt den Index über den Manticore/sql?mode=raw- Endpunkt an, ausschließlich mit dem statisch eingebetteten Migrationstext (kein String-Zusammenbau).Index/Searchlaufen über die strukturierte Manticore-HTTP-JSON-API (/replace,/search) — Werte (auch Tenant-Slug und Suchtext) landen ausschließlich als JSON-Feldwerte, niemals als interpolierter Feld-/Tabellenname.Searchfiltert zwingend überFieldTenantSlug(Akzeptanzkriterium 3).
- Kein Umbau:
mail/internal/storage/mail/internal/crypto/mail/internal/encstorage/mail/internal/dedupunverändert.
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Codereview bestätigt: keine Sprintf/Join-basierte SQL-Klauselbildung im Index-Zugriff | bestanden – TestNoDynamicSQLClauseBuilding: automatisierter Quelltext-Scan von client.go bestätigt, dass kein fmt.Sprintf verwendet wird und in der Nähe des /sql?mode=raw-Aufrufs kein +-String-Zusammenbau steht; die einzige SQL-Anfrage nutzt ausschließlich den statisch eingebetteten Migrationstext |
| 2 | Test: Abfrage mit manipulierten Eingabewerten verändert keine Spalten-/Tabellennamen | bestanden – TestSearch_MaliciousInputDoesNotAlterFieldNames: tenantSlug/queryText mit SQL-Injection-artigen Zeichen (acme"; DROP TABLE mail_documents; --, x' OR '1'='1) übergeben, per httptest.Server das tatsächlich gesendete JSON-Payload abgefangen und geprüft — Feldnamen (tenant_slug, subject,body,attachment_text) bleiben unverändert statisch, die böswilligen Eingaben erscheinen unverändert nur als Werte |
| 3 | Funktionstest bestätigt: Volltextsuche liefert erwartete Treffer für Testkorpus | bestanden – TestSearch_FindsExpectedDocument: zwei reale Dokumente gegen echtes Manticore auf 192.168.1.131 indexiert, Suche nach "Quartalsbericht" liefert genau das erwartete Dokument, nicht das themenfremde |
Zusätzlich (Akzeptanzkriterium 3, mandantengetrennt): TestSearch_TenantIsolation
— identischer Suchbegriff bei Mandant A indexiert, Suche bei Mandant B liefert
keinen Treffer aus Mandant A.
Build/Test-Ergebnis (192.168.1.131)
go build ./... -> clean
go vet ./... -> clean
golangci-lint run ./... -> 0 issues
TEST_TENANT_DSN=postgresql://nexarch_test:***@localhost:5432/tenant_acme?sslmode=disable \
TEST_MANTICORE_URL=http://127.0.0.1:9308 \
go test ./... -v -p 1 -> alle Pakete bestanden, inkl. internal/search (4 Tests)
Manticore lief bereits produktiv auf 192.168.1.131 (Port 9308, Version 7.4.1,
Dienst manticore.service aktiv seit 2026-08-28). Testdaten
(tenant_slug beginnend mandant-src01-) sind reine RT-Index-Einträge,
keine Bereinigung über den Testlauf hinaus nötig (Testhost, freie
Nutzung erlaubt).
Gesamtergebnis
Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt. Entsperrt SRC-02, SRC-03, SRC-09.