106 lines
7.0 KiB
Markdown
106 lines
7.0 KiB
Markdown
# 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
|