Vault initial

This commit is contained in:
Hermes (Server)
2026-08-17 10:56:15 +02:00
parent 26cc1e86b0
commit 3274c11938
12 changed files with 625 additions and 192 deletions
@@ -0,0 +1,105 @@
# Audit 14.08.2026 Sicherheit & Code-Review
> Stand: 14.08.2026
> Umfang: Server Aingrad (Sicherheit + Aufräumen) und Melo App (Code-Review)
> Alle Änderungen live verifiziert · Backups: `/home/dustin/backup-audit-2026-08-14/`
---
## ⚠️ Zuerst: Zwei Korrekturen an bestehenden Notizen
**1. Die Neustart-Befehle in [[Server Aingrad - Komplette Übersicht]] sind gefährlich.**
Dort steht noch:
```bash
sudo pkill -f baka_auth.py && python3 /home/dustin/scripts/baka_auth.py 8994 &
```
Die drei Dienste laufen inzwischen als **systemd-Units mit `Restart=always`**. Der Befehl killt den verwalteten Prozess, systemd startet ihn sofort neu und belegt den Port — der manuell gestartete Prozess scheitert dann an `Address already in use`, oder er gewinnt das Rennen und läuft unverwaltet weiter, bis die Shell endet. Richtig ist:
```bash
sudo systemctl restart baka-auth # Port 8994
sudo systemctl restart melo-cloud # Port 8993
sudo systemctl restart yt-proxy # Port 8992
sudo systemctl status baka-auth # Zustand prüfen
```
**2. Die Dienst-Tabelle ist beim Zugriff überholt.** `search.baka-net.de` steht dort als „Offen" — seit heute Basic Auth. Ebenfalls nicht erfasst: `matrix`, `element`, `admin-matrix`, `livekit`, `workspace`, `crash`, `ladder`.
---
## 🔒 Behobene Sicherheitslücken
| Befund | Fix | Verifiziert |
|--------|-----|-------------|
| `/whoami` Auth-Bypass: Basic-Header wurde ohne Passwortprüfung geglaubt → jeder bekam `is_admin: true` | Caddy prüft das Passwort vor dem Proxy | 401 statt 200 |
| `/api/cloud/yt-finder` vor der Auth-Prüfung → jeder Request startet 120-s-Subprozess | Doppelte Route entfernt | 401 sofort |
| `ladder` offener Paywall-Proxy (Abuse auf eigene IP) | Basic Auth | 401 |
| `search` offene SearXNG | Basic Auth | 401 |
| `admin-matrix` Synapse-Panel offen | Basic Auth | 401 |
| Navidrome-Admin-Passwort im Klartext in `baka_auth.py` | → `/etc/baka-auth/navidrome_pw` (640 root:dustin) | Sync getestet |
| `handle_profile` listete bei Fehler alle Benutzernamen | Meldung neutralisiert | — |
| Share-Codes aus `random` (vorhersagbar) | `secrets.choice`, 6 → 8 Zeichen | alte Codes gültig |
| `baka_auth` single-threaded → Logins serialisiert hinter Navidrome-Timeouts | ThreadingWSGIServer + `threading.Lock` fürs Rate-Limit | Login getestet |
Caddy nutzt jetzt ein Snippet `(baka_users)` — Benutzerliste steht **an einer Stelle** statt viermal dupliziert.
---
## 🛑 Wichtigster Fund: Prod-Build von workspace umgeht die Auth
`hermes-workspace` läuft absichtlich mit `pnpm dev`. Der naheliegende „Fix" (Produktions-Build) wurde getestet — **auf separatem Port 3021, ohne den laufenden Dienst anzufassen**:
| Route | Dev (3020) | Prod (3021) |
|-------|-----------|-------------|
| `/api/sessions` | `{"ok":false,"error":"Unauthorized"}` | **200 + echte Chat-Titel, Previews, Token-Zahlen** |
| `/api/files` | 401 | **200** |
Der Produktions-Build setzt die Authentifizierung nicht durch. Eine Umstellung hätte sämtliche Agent-Konversationen öffentlich gemacht. **Nicht auf `node server-entry.js` umstellen, bevor die Auth-Middleware im SSR-Pfad repariert ist.** Prüfkommando danach:
```bash
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:PORT/api/sessions # muss 401 sein
```
Verbleibender Nachteil des Dev-Servers: er liefert serverseitigen Quellcode aus (`/src/server/auth-middleware.ts`, `/vite.config.ts` → 200). **Keine Secrets betroffen**`.env` und `/@fs/`-Zugriffe sind mit Vite 7.3.5 korrekt geblockt (403), im ausgelieferten Code stehen nur Variablennamen.
---
## 🎵 Melo App & Cloud
**Upload-Datenverlust behoben.** `upload()` verknüpfte bei >85 % Titel-Ähnlichkeit auf einen bestehenden Song und **verwarf die hochgeladene Datei** — Live-Versionen und Remixes wurden durch das Studio-Original ersetzt. Entfernt. Begründung durch Messung: 323 von 325 Songs haben einen gültigen Fingerprint (99,4 %), `fpcalc` läuft. Greift der Fingerprint nicht, ist das Audio nachweislich anders; ein Dateiname darf das nicht überstimmen.
End-to-End getestet (zwei verschiedene Audios, 94 % ähnliche Namen): neu → `new`, identisch → `linked` (SHA256-Dedup intakt), anderes Audio → `new` mit eigener ID. Gespeicherte Dateien byte-identisch mit den Originalen. Testdaten restlos entfernt (wieder 325 Songs, 0 verwaiste Einträge).
**`cgi`-Modul ersetzt.** Multipart-Parsing läuft jetzt über die stdlib (`email`); `cgi` ist seit Python 3.13 entfernt (PEP 594) — der Upload wäre beim Distro-Upgrade wortlos ausgefallen. Gegen `cgi.FieldStorage` byte-identisch getestet (Nullbytes, CRLF, Boundary-Sequenzen, Umlaute).
**`deletePlaylist` repariert.** Schickte POST auf `/api/v1/cloud/playlists`; der Server unterscheidet dort nach Methode (POST = anlegen, DELETE = löschen). Das Löschen landete im Anlegen-Handler, scheiterte an der Namensprüfung und lieferte HTTP 200 mit `status: error` — die UI meldete trotzdem Erfolg, die Playlist blieb. Jetzt DELETE, Rückgabewert wird ausgewertet, 3 Regressionstests.
- **202 Tests grün** (vorher 199), `flutter analyze` ohne Befund
- Commit `2223813` auf Branch `fix/cloud-playlist-delete`, noch nicht auf `main`
- `main` hat zusätzlich `v2.56.2` ungepusht
---
## 🧹 Aufgeräumt (~5 GB, 179 G → 184 G frei)
APT-Cache (1,1 G) · Build-Output des veralteten Duplikats `git/melo_app` (3,0 G) · npm-Cache · `gateway-restart.log` (29 M → 428 K) · drei leere Alt-Datenbanken in `/var/lib/melo-cloud/`.
**Nicht angefasst:** `.gradle/caches` (5,2 G) und `.hermes/profiles/server-security/home` (9,3 G — zweites Home mit eigenem Flutter, Chrome, Claude-Versionen). Beides regenerierbar, aber teuer bzw. potenziell in Benutzung.
---
## 📌 Offene Themen
- **`/home/dustin/scripts` ist kein Git-Repo.** ~3400 Zeilen Python tragen Auth und Musik-Cloud, völlig unversioniert. Einziger Schutz sind die Backups von heute. Eigenes Repo dringend empfohlen (`.gitignore` für `__pycache__` und Secrets).
- **Auth-Middleware im SSR-Pfad von workspace** — Blocker für jeden Prod-Build.
- **Versionsstrings der App widersprechen sich:** `main.dart:32` → 2.56.1, `settings_screen.dart:364` → 2.56.1, `settings_screen.dart:500` → 2.56.0, `home_screen.dart:1236` → 2.56.0. Nirgends 2.56.2. Besser eine Konstante, auf die alle vier zeigen.
- **Passwortloses sudo bleibt bewusst.** `backup_and_cleanup.sh` läuft per Cron täglich 04:00 und braucht es — global entfernen bricht das Backup still. Falls Härtung: NOPASSWD auf die konkret nötigen Befehle einschränken und den Cron-Lauf testen.
- **`_download`/`_stream` in `melo_cloud.py`** lesen ganze Dateien in den RAM (`fh.read()`), ebenso `download()` in der App (`r.bodyBytes`). Bei 50-MB-Songs und 7,7 GB RAM perspektivisch ein Thema.
- Basic-Auth-Passwörter (`baka`, `dustin`, `tinker`) schützen jetzt deutlich mehr als vorher — falls eins schwach ist, wäre das der nächste Schritt.
---
## Verwandte Notizen
- [[Server Aingrad - Komplette Übersicht]] — Dienst-Tabelle und Neustart-Befehle oben korrigieren
- [[Melo App - Status]] — Stand dort ist v2.53.1, aktuell ist v2.56.2 + Fix-Branch