# Sicherheit ## Überblick Was der Client tut, wem er vertraut und was in der Verantwortung des Projekts bleibt. ## Das Token Das Instanz-Token ist ein 64-stelliger Hexadezimalwert aus 32 zufälligen Bytes. Es ist das einzige Geheimnis zwischen Instanz und Server. - Es wird **einmalig** beim Anlegen der Instanz angezeigt. Der Server speichert nur den SHA-256-Hash und kann es nicht wieder ausgeben. - Es steht ausschließlich in `manage-client/config.php`. - Diese Datei gehört **nicht ins Repository** und **nicht ins Release-Paket**. - Bei Verdacht auf Kompromittierung im Manage-Server unter **Instanzen** → "Token erneuern". Das alte Token ist damit sofort ungültig. ```gitignore manage-client/config.php data/manage/ ``` Ein kompromittiertes Token erlaubt: Releases herunterzuladen und Backups hochzuladen – also Zugriff auf den Anwendungscode und das Belegen von Speicherplatz. Es erlaubt **nicht**, Backups herunterzuladen oder Releases zu verändern; beides geht nur über die Anmeldung am Manage-Server. ## Transport Alle Anfragen laufen über HTTPS. Der Client verwendet die PHP-Standardeinstellungen für die Zertifikatsprüfung; diese wird **nicht** abgeschaltet. Ein Server mit selbstsigniertem Zertifikat funktioniert deshalb nicht ohne passendes CA-Bundle im System – das ist Absicht. Umleitungen werden nicht verfolgt (`follow_location => 0`). Eine umgeleitete Anfrage schlägt fehl, statt Zugangsdaten an ein anderes Ziel zu senden. ## Vertrauen ins Release-Paket Ein Update rollt fremden Code auf dem Server aus. Abgesichert ist das durch: 1. **TLS** zum Manage-Server. 2. **Token-Pflicht** für Manifest und Paket – beides ist nicht öffentlich abrufbar. 3. **SHA-256-Prüfung** von Größe und Inhalt gegen das Manifest. Bei Abweichung wird die Datei gelöscht und nichts ausgerollt. 4. **Pfadprüfung** jedes ZIP-Eintrags gegen Ausbruch aus dem Zielverzeichnis. 5. **Plausibilitätsprüfung** über `MANAGE_UPDATE_SANITY_PATHS`. Die Grenze dieses Modells: Die Prüfsumme kommt vom selben Server wie das Paket. Wer den Manage-Server übernimmt, kann ein Paket **und** die passende Prüfsumme veröffentlichen. Eine Signatur mit einem im Client hinterlegten öffentlichen Schlüssel gibt es bewusst nicht – der Manage-Server muss entsprechend abgesichert werden. ## Backups enthalten Betriebsdaten Ein Backup wird an den Manage-Server übertragen, dort gespeichert und kann von jedem heruntergeladen werden, der sich am Manage-Server anmeldet. Daraus folgt: - **Keine Zugangsdaten ins Backup.** `config.php` mit Datenbankpasswörtern oder API-Schlüsseln gehört nicht in `MANAGE_BACKUP_SOURCES`. - Enthält das Backup personenbezogene Daten – bei Bestell- oder Kundendaten die Regel – gelten für den Manage-Server dieselben Anforderungen wie für die Anwendung selbst: Zugriffsschutz, Verschlüsselung im Transport, Löschfristen. Die Aufbewahrung auf dem Server ist einstellbar. - Das S3-Ziel legt Archive unverschlüsselt im Bucket ab. Der Bucket muss privat sein. ## Lokale Verzeichnisse Diese Verzeichnisse dürfen nicht über das Web erreichbar sein: | Pfad | Inhalt | |---|---| | `data/manage/backups/` | vollständige Betriebsdaten | | `data/manage/updates/` | Kopien der überschriebenen Anwendungsdateien | | `data/manage/work/` | entpackte Pakete während eines Updates | | `manage-client/config.php` | Instanz-Token | Das mitgelieferte `manage-client/.htaccess` sperrt `config.php`, `lib/` und `bin/`. Für `data/` ist die `.htaccess` des Projekts zuständig. Auf nginx müssen die entsprechenden `location`-Regeln von Hand gesetzt werden – dort greift keine `.htaccess`. Prüfen lässt sich das direkt: ```bash curl -s -o /dev/null -w "%{http_code}\n" https://meinprojekt.example.org/manage-client/config.php curl -s -o /dev/null -w "%{http_code}\n" https://meinprojekt.example.org/data/manage/backups/ ``` Beides muss `403` oder `404` liefern, niemals `200`. ## Die Oberfläche `ui/panel.php` erlaubt es, Updates auszurollen und Backups herunterzuladen – es ist die mächtigste Seite der Anwendung. Deshalb: - Das Projekt muss seine Anmeldung **vor** dem Einbinden prüfen. - Das Panel bringt eine zusätzliche Prüfung auf `$_SESSION["admin_logged_in"]` mit. - `MANAGE_PANEL_SKIP_AUTH_GUARD` deaktiviert nur diese zusätzliche Prüfung. Wer sie setzt, ohne selbst zu prüfen, veröffentlicht Update- und Backup-Funktionen im Netz. - Alle Formulare sind CSRF-geschützt. - Der Download validiert den Dateinamen streng, damit kein beliebiger Pfad ausgeliefert werden kann. Nach Möglichkeit sollte die Seite nur Administratoren zugänglich sein, nicht allen angemeldeten Benutzern. ## Kommandozeile `bin/manage-client.php` verweigert die Ausführung über HTTP (`PHP_SAPI`-Prüfung) und ist zusätzlich per `.htaccess` gesperrt. Auf dem Server sollte die Datei trotzdem nicht im öffentlichen Verzeichnisbaum liegen, wenn sich das vermeiden lässt. ## Protokolle Das Client-Protokoll enthält Dateinamen, Versionen, HTTP-Status und Fehlermeldungen. Zugangsdaten werden ausgefiltert: Aus Zielkonfigurationen übernimmt der Client nur eine Positivliste unkritischer Schlüssel; `access_key`, `secret_key`, `password` und das Instanz-Token erscheinen nie im Protokoll. Antwortauszüge von fehlgeschlagenen Uploads werden auf 500 Zeichen gekürzt. ## Checkliste vor dem Produktivgang - [ ] `manage-client/config.php` ist in `.gitignore` - [ ] `config.php` und `manage-client/config.php` sind aus dem Release-Paket ausgeschlossen - [ ] `data/manage/` ist über das Web nicht erreichbar (geprüft mit `curl`) - [ ] `manage-client/config.php` ist über das Web nicht erreichbar (geprüft mit `curl`) - [ ] Die Panel-Seite verlangt eine Administrator-Anmeldung - [ ] `MANAGE_SERVER_URL` verwendet `https://` - [ ] Im Backup stecken keine Zugangsdaten - [ ] Ein Backup wurde einmal heruntergeladen und der Inhalt geprüft ## Weiter - [08_PROTOCOL](08_PROTOCOL.md) – Authentifizierung im Detail - [05_BACKUP_SOURCES](05_BACKUP_SOURCES.md) – was ins Archiv gehört