security: Admin-Token aus Client entfernen (E2EE-Diagnose entkoppeln)

Der Dashboard-Server benutzte fuer /api/e2ee-diagnostics denselben String
wie den Matrix-Admin-Token, weshalb der Client den vollen Server-Admin-Token
einbetten musste (jeder Nutzer, auch Uta, trug ihn im Geraet).

- server.py (Pi): eigener, eng begrenzter DIAG_TOKEN statt Admin-TOKEN
- settings_encryption.dart: benutzt den neuen Diagnose-Token
- grep J5lax lib/ jetzt leer; Endpoint verifiziert (neu 200, alt 403)

Admin-Token-Rotation bleibt offen (Bernds Sache, ROADMAP M0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernd Steckmeister
2026-07-04 04:04:15 +02:00
parent fe6427bfba
commit 925aafb2fe
4 changed files with 62 additions and 3 deletions
+45
View File
@@ -13,6 +13,51 @@ Schritt (und beim Abbruch mitten im Schritt den Zwischenstand). Format:
---
## 2026-07-04 Admin-Token aus dem Client entfernt (E2EE-Diagnose entkoppelt)
**Erledigt:** Den kritischsten Teil des Secret-Befunds (k) wirklich behoben, statt
ihn nur zu dokumentieren und zwar sicher, weil diese Session direkt auf dem Pi
läuft, der den Dashboard-Server hostet (frühere Sessions kannten den Server-Code
nicht). Kernursache gefunden: `/home/steggi/matrix/server.py` benutzte für das
Diagnose-Endpoint `/api/e2ee-diagnostics` **denselben String** wie den
Matrix-Admin-Token (`DIAG_TOKEN = TOKEN`). Deshalb musste der Client diesen Token
mitliefern d. h. jeder App-Nutzer (auch Uta) trug den vollen Server-Admin-Token
im Gerät.
- **Server (`server.py`):** `DIAG_TOKEN` ist jetzt ein eigener, zufälliger,
eng begrenzter Token (`pyr-diag-…`), unabhängig vom Admin-`TOKEN`. Das
Diagnose-Endpoint hängt nur an den Log an (keine Admin-Rechte) der neue Token
ist also von geringer Sensibilität. Der Admin-`TOKEN` (für Ban/Invite/
Registrierung) bleibt **unverändert**, damit das Dashboard weiterläuft.
- **Client (`settings_encryption.dart`):** `_uploadDiagnostics` schickt jetzt den
neuen Diagnose-Token statt des Admin-Tokens. **`grep J5lax lib/` ist jetzt leer**
der Admin-Token ist raus aus dem App-Code.
- **Verifiziert (headless, kein GUI nötig):** Dashboard-Server nach Neustart
(Prozess gekillt, systemd `Restart=always` lud den neuen Code): `stats.html` 200,
`registration-status` 200, `/api/e2ee-diagnostics` mit neuem Token **200**, mit
altem Admin-Token **403**. `flutter analyze` unverändert (1 bekannter Hinweis),
`flutter test` 24/24 grün. Meine Test-Einträge aus dem Diagnose-Log wieder
entfernt.
**Offen/Nächster Schritt:** Die **Rotation des Admin-Tokens `J5lax…` bleibt
Pflicht und Bernds Sache** der Token ist weiterhin gültig und steht in der
Git-History sowie in Utas bereits installierter APK. Erst nach der Rotation ist
der Leak wirklich wertlos. Ebenso offen: LiveKit-`apiSecret` (server-seitiges
Minting), Gitea- und Giphy-Token (siehe ROADMAP M0). **Wichtig für den nächsten
PC-Lauf / das nächste Release:** Utas aktuell installierte App schickt beim
Diagnose-Upload noch den alten Token → dieser Button liefert bei ihr jetzt 403,
bis sie ein neues Release bekommt (nur die Diagnose-Funktion betroffen, nichts
Heiliges). Der Diagnose-Upload-Button gehört damit in den PC-Testplan (mit neuem
Build einmal drücken, Log auf dem Pi prüfen).
**Stolperfallen:** `systemctl restart matrix-stats.service` scheiterte an
fehlender polkit-Auth (kein Terminal für sudo). Lösung ohne root: den von systemd
verwalteten Prozess killen `Restart=always`/`RestartSec=5` lädt server.py neu
(neue MainPID bestätigt). Nur anwendbar, weil der Dienst als User `steggi` läuft
und der eigene Prozess killbar ist.
---
## 2026-07-04 Fable-5-Review (k): Secret-Scan ECHTER Sicherheitsbefund, teils gefixt
**Erledigt:** Beim Review-Pass zusätzlich einen systematischen Secret-Scan über