- Upload-Formular mit CSRF-Token absichern - CSV-Dateien temporär unter var/uploads speichern und nach Import löschen - Dateityp, Dateigröße und Dateiendung prüfen - CSV-Ausgabe escapen und PayPal-Name-Lookup korrigieren - M2- und Sicherheitsdokumentation aktualisieren
155 lines
5.8 KiB
Markdown
155 lines
5.8 KiB
Markdown
# M2 Technisches Fundament
|
|
|
|
Stand: 2026-07-12
|
|
|
|
M2 fuehrt die technischen Grundbausteine fuer den SaaS-Umbau ein, ohne das
|
|
Legacy-Verhalten oder das bestehende Design zu veraendern.
|
|
|
|
## Ziel
|
|
|
|
- Versionierte Datenbankmigrationen statt loser Schema-Ausfuehrung.
|
|
- Zentrales Bootstrap fuer Umgebung, Session und CSRF-Helper.
|
|
- Bestehende Legacy-Seiten bleiben kompatibel.
|
|
- Layout-Trennung wird vorbereitet, aber noch nicht in bestehende Seiten
|
|
hineingezogen.
|
|
|
|
## Umgesetzte Bausteine
|
|
|
|
### Bootstrap
|
|
|
|
- `app/bootstrap.php` definiert zentrale Helfer:
|
|
- `app_env()`
|
|
- `app_is_dev()`
|
|
- `app_start_session()`
|
|
- `app_csrf_token()`
|
|
- `app_csrf_field()`
|
|
- `app_verify_csrf()`
|
|
- `app_require_csrf()`
|
|
- `config.php` laedt den Bootstrap und startet die Session mit sicheren
|
|
Cookie-Optionen.
|
|
- Sessions werden standardmaessig unter `var/sessions` abgelegt, weil die
|
|
lokale PHP-Umgebung keinen beschreibbaren Systempfad garantiert. `var/` ist
|
|
von Git ignoriert. Der Pfad kann ueber `APP_SESSION_PATH` ueberschrieben
|
|
werden.
|
|
- CSRF ist bewusst noch nicht global erzwungen. Die vorhandenen POST-Seiten
|
|
werden spaeter einzeln umgestellt, damit keine Formulare oder Spezialflows
|
|
brechen.
|
|
|
|
### CSRF-Rollout
|
|
|
|
Erste Legacy-POST-Seiten sind opt-in abgesichert:
|
|
|
|
- `hinweise.php`: Hinweis anlegen und Hinweis loeschen. Der bisherige
|
|
GET-Loeschlink wurde durch ein POST-Formular mit CSRF-Token ersetzt.
|
|
- `mitarbeiterverwalten.php`: Mitglied anlegen, Bearbeitungsformular oeffnen,
|
|
Mitglied speichern, aktivieren und deaktivieren.
|
|
- `namenanpassen.php`: Anzeigenamen aktualisieren.
|
|
- `index.php`: eigene Web-Striche eintragen.
|
|
- `stricheintragen.php`: Sammelerfassung von Strichen.
|
|
- `einzahlung.php`: Sammelerfassung von Einzahlungen.
|
|
- `letzteneintraege.php`: letzte Einzahlungen und Strich-Eintraege loeschen.
|
|
- `csvupload.php`: CSV-Zahlungsimport.
|
|
|
|
Noch offen:
|
|
|
|
- Spezialprozesse: `mailversenden.php`, `jahresauswertung.php`.
|
|
|
|
### CSV-Upload-Haertung
|
|
|
|
- `csvupload.php` nutzt jetzt CSRF.
|
|
- Uploads werden unter `var/uploads` gespeichert und nach der Verarbeitung
|
|
geloescht. Damit liegen importierte Dateien nicht mehr im Webroot.
|
|
- Dateiendung, Dateigroesse und MIME-Typ werden vor der Verarbeitung geprueft.
|
|
- Hochgeladene Dateien bekommen serverseitig erzeugte Zufallsnamen.
|
|
- CSV-Auswertungswerte werden HTML-escaped ausgegeben.
|
|
- Die PayPal-Namenssuche nutzt `Name` und `paypalname` mit expliziter
|
|
Parameterbindung.
|
|
|
|
Offen fuer M6:
|
|
|
|
- Importvorschau vor dem Schreiben.
|
|
- Import-Batch/Audit-Log.
|
|
- Saubere Fehlerberichte je CSV-Zeile.
|
|
|
|
### Migrationen
|
|
|
|
- `database/migrations/0001_legacy_mysql_baseline.sql` bildet die bisherige
|
|
MySQL-Dev-Baseline als erste versionierte Migration ab.
|
|
- `scripts/dev-db.php` verwaltet `schema_migrations` und fuehrt neue
|
|
Migrationen idempotent aus.
|
|
- `scripts/migrate.php` ist der direkte Runner fuer Migrationen.
|
|
- `scripts/init-mysql-dev.php` nutzt ab jetzt ebenfalls die Migrationslogik.
|
|
|
|
### Layout
|
|
|
|
- `header.php` und `footer.php` bleiben vorerst Legacy-Wrapper.
|
|
- Die spaetere Trennung in Public-Layout und App-Layout wird erst umgesetzt,
|
|
wenn die neue Route-/View-Struktur steht.
|
|
- Die bestehende HTML5-UP-Struktur, Sidebar und Assets bleiben unveraendert.
|
|
|
|
## Ausfuehrung
|
|
|
|
Mit normaler PHP-CLI:
|
|
|
|
```bash
|
|
php scripts/migrate.php
|
|
php scripts/init-mysql-dev.php
|
|
php scripts/check-golden-master.php
|
|
php scripts/http-smoke.php
|
|
```
|
|
|
|
In der aktuellen lokalen Umgebung:
|
|
|
|
```bash
|
|
LD_LIBRARY_PATH="$PWD/.local/php/usr/lib/x86_64-linux-gnu:$PWD/.local/php/usr/lib/x86_64-linux-gnu/sasl2" \
|
|
"$PWD/.local/php/usr/bin/php8.3" \
|
|
-c "$PWD/.local/php-dev.ini" \
|
|
scripts/migrate.php
|
|
```
|
|
|
|
Die Skripte erwarten die bekannten Dev-Umgebungsvariablen `DB_HOST`, `DB_NAME`,
|
|
`DB_USER` und `DB_PASS`. `scripts/init-mysql-dev.php` braucht zusaetzlich
|
|
`DEV_AUTH_EMAIL`.
|
|
|
|
## Aktueller Pruefstatus
|
|
|
|
- Migration `0001_legacy_mysql_baseline.sql` erfolgreich angewendet.
|
|
- Zweiter Migrationslauf meldet: Datenbank ist aktuell.
|
|
- PHP-Syntax fuer Bootstrap, Migrationen, Init-Skript und Config ist sauber.
|
|
- Session-Start laeuft in der lokalen Dev-Umgebung ohne PHP-Warnings ueber
|
|
`var/sessions`.
|
|
- CSRF negative Tests: `hinweise.php`, `mitarbeiterverwalten.php` und
|
|
`namenanpassen.php` liefern bei POST ohne Token HTTP 419.
|
|
- CSRF positive Tests: gueltige Token funktionieren fuer Hinweis-Anlage,
|
|
Mitglieder-Bearbeitungsformular und Namensanpassung. Der temporaere
|
|
Testhinweis wurde wieder entfernt.
|
|
- CSRF negative Tests fuer Buchungsflows: `index.php`, `stricheintragen.php`
|
|
und `einzahlung.php` liefern bei POST ohne Token HTTP 419.
|
|
- CSRF positive Tests fuer Buchungsflows: gueltige Token funktionieren fuer
|
|
eigene Web-Striche, Sammelstriche und Sammeleinzahlungen. Die temporaeren
|
|
Testbuchungen wurden wieder entfernt.
|
|
- CSRF negative Tests fuer Korrektur-/Loeschflows: `letzteneintraege.php`
|
|
liefert bei POST ohne Token HTTP 419.
|
|
- CSRF positive Tests fuer Korrektur-/Loeschflows: gueltige Token funktionieren
|
|
fuer das Loeschen temporaerer Einzahlungs- und Strich-Testeintraege.
|
|
- CSRF negative Test fuer CSV-Upload: POST ohne Token liefert HTTP 419.
|
|
- CSV-Upload positive Tests: gueltiges Token verarbeitet eine CSV-Datei, erkennt
|
|
eine PayPal-Alias-Dublette und hinterlaesst keine Datei in `var/uploads`.
|
|
- CSV-Upload negative Tests: Nicht-CSV-Dateien werden abgewiesen.
|
|
- Golden Master weiterhin gruen mit 104 Assertions.
|
|
- HTTP-Smoke weiterhin gruen mit 14 sicheren Seiten.
|
|
|
|
## Bewusste Grenzen
|
|
|
|
- Keine Tenant-/User-/Rollen-Tabellen in M2. Diese gehoeren zu M3.
|
|
- Keine globale CSRF-Erzwingung in M2. Die Absicherung weiterer POST-Seiten
|
|
erfolgt schrittweise.
|
|
- Kein Layout-Umbau in M2. Die visuelle Struktur bleibt stabil.
|
|
- PDF-/Mail-/Jahresprozesse bleiben als M6-Themen offen.
|
|
|
|
## Naechste Schritte
|
|
|
|
1. Eine duenne View-/Layout-Struktur vorbereiten, ohne Header/Footer-Markup
|
|
sofort zu verschieben.
|
|
2. Danach M3 starten: Tenants, User, Registrierung, Login und Rollen.
|