CSV-Upload gegen CSRF und unsichere Ablage härten

- 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
This commit is contained in:
2026-07-12 10:13:56 +02:00
parent e5fd47ecf6
commit 30378683e6
4 changed files with 144 additions and 40 deletions
+4 -4
View File
@@ -11,9 +11,9 @@ Testing, markiert aber die wichtigsten Risiken fuer die SaaS-Umstrukturierung.
| --- | --- | --- | --- |
| Hart codierte DB-Zugangsdaten | `jahresauswertung.php` Zeilen 4-8 | Secret-Leak, direkte Produktiv-DB-Gefahr | Zugangsdaten rotieren, Skript deaktivieren oder auf Env-Konfiguration umstellen |
| Schreibende Seiten ohne eigene Rollenpruefung | `stricheintragen.php`, `einzahlung.php`, `mailversenden.php`, `exportKaffeeliste.php` | Direkter URL-Aufruf kann Aktionen erlauben | Jede Seite serverseitig mit `requireRole` absichern |
| CSRF-Schutz nur teilweise vorhanden | viele POST-/Delete-Formulare; M2 hat `hinweise.php`, `mitarbeiterverwalten.php`, `namenanpassen.php`, `index.php`, `stricheintragen.php`, `einzahlung.php`, `letzteneintraege.php` abgesichert | Ungewollte Buchungen, Loeschungen, Imports | CSRF fuer alle verbleibenden schreibenden Aktionen |
| CSRF-Schutz nur teilweise vorhanden | viele POST-/Delete-Formulare; M2 hat `hinweise.php`, `mitarbeiterverwalten.php`, `namenanpassen.php`, `index.php`, `stricheintragen.php`, `einzahlung.php`, `letzteneintraege.php`, `csvupload.php` abgesichert | Ungewollte Buchungen, Loeschungen, Imports | CSRF fuer alle verbleibenden schreibenden Aktionen |
| Harte Deletes fuer Buchungen | `letzteneintraege.php` | Audit-Historie und Revisionsfaehigkeit gehen verloren | Storno-/Reversal-Modell statt Delete |
| Upload in Webroot | `csvupload.php` Zeilen 131-138 | Dateiablage kann missbraucht werden | Upload ausserhalb Webroot, Dateityp/MIME/Name pruefen |
| CSV-Upload nur teilweise gehaertet | `csvupload.php`; M2 speichert temporaer unter `var/uploads`, prueft Dateityp und loescht nach Import | Ohne Importvorschau/Audit bleiben Fehlimporte schwer nachvollziehbar | Importvorschau, Batch-/Audit-Log und detaillierte Zeilenfehler in M6 |
| Kein Tenant-Scope | alle fachlichen Queries | Zentrales SaaS-Leak-Risiko | `tenant_id` verpflichtend und Query-Schicht testen |
## Weitere Befunde
@@ -25,7 +25,7 @@ Testing, markiert aber die wichtigsten Risiken fuer die SaaS-Umstrukturierung.
| Datumsformat `Y-d-m H:i:s` | `index.php`, `stricheintragen.php`, `einzahlung.php`, `hinweise.php` | ISO/DB-kompatibel `Y-m-d H:i:s` oder DB-Zeit verwenden |
| Ausgabe von Namen/E-Mails teils unescaped | mehrere Tabellen, z.B. Mitgliederverwaltung | `htmlspecialchars` zentral erzwingen |
| Fehlerausgabe mit `sqlsrv_errors()` an Nutzer | mehrere Dateien | Logging intern, neutrale Fehlermeldung extern |
| CSV-Mitarbeitersuche mit mutmasslich falscher Parameteranzahl | `csvupload.php` `getMitarbeiterID` | Query pruefen und mit Tests abdecken |
| CSV-Mitarbeitersuche mit mutmasslich falscher Parameteranzahl | `csvupload.php` `getMitarbeiterID`; in M2 korrigiert | Mit Golden-Master weiter pruefen |
| Basis-Auth-Beispiel mit Platzhalter-Passwort | `umfrageergebnisse.php` Kommentarblock | Entfernen oder echte Auth-Middleware nutzen |
| App-Navigation ist in `footer.php` | Layoutstruktur | Trennung in App-Shell und Public-Shell |
| `headerline.php` enthaelt NUL-Zeichen | `headerline.php` | Datei pruefen/entfernen, wenn ungenutzt |
@@ -54,7 +54,7 @@ Fuer SaaS gilt:
2. Legacy-Schreibseiten bis zum Umbau hinter explizite Admin-Pruefung setzen.
3. CSRF-Schutz schrittweise auf alle verbleibenden Legacy-Schreibseiten ausrollen.
4. Finanzdaten im Zielmodell nur noch stornieren, nicht loeschen.
5. Uploads ausserhalb des Webroots modellieren.
5. CSV-Import mit Vorschau, Audit und Zeilenfehlern modellieren.
6. Einheitliche Escape-/View-Helfer einfuehren.
7. Tenant-Isolation mit Tests gegen zwei Tenants absichern.
+24 -5
View File
@@ -48,12 +48,29 @@ Erste Legacy-POST-Seiten sind opt-in abgesichert:
- `stricheintragen.php`: Sammelerfassung von Strichen.
- `einzahlung.php`: Sammelerfassung von Einzahlungen.
- `letzteneintraege.php`: letzte Einzahlungen und Strich-Eintraege loeschen.
- `csvupload.php`: CSV-Zahlungsimport.
Noch offen:
- Uploads: `csvupload.php`.
- 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
@@ -115,6 +132,10 @@ Die Skripte erwarten die bekannten Dev-Umgebungsvariablen `DB_HOST`, `DB_NAME`,
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.
@@ -128,8 +149,6 @@ Die Skripte erwarten die bekannten Dev-Umgebungsvariablen `DB_HOST`, `DB_NAME`,
## Naechste Schritte
1. CSV-Upload gesondert absichern und spaeter Uploads ausserhalb des Webroots
verlegen.
2. Eine duenne View-/Layout-Struktur vorbereiten, ohne Header/Footer-Markup
1. Eine duenne View-/Layout-Struktur vorbereiten, ohne Header/Footer-Markup
sofort zu verschieben.
3. Danach M3 starten: Tenants, User, Registrierung, Login und Rollen.
2. Danach M3 starten: Tenants, User, Registrierung, Login und Rollen.
+4 -1
View File
@@ -384,7 +384,10 @@ Schritte:
globale Erzwingung erfolgt schrittweise pro POST-Seite. Erste Seiten sind
abgesichert: `hinweise.php`, `mitarbeiterverwalten.php`,
`namenanpassen.php`, `index.php`, `stricheintragen.php`, `einzahlung.php`,
`letzteneintraege.php`.
`letzteneintraege.php`, `csvupload.php`.
- CSV-Upload ausserhalb des Webroots speichern. In M2 als Legacy-Haertung
umgesetzt: temporaer unter `var/uploads`, Dateityp-/Groessenpruefung und
Loeschung nach Verarbeitung.
- Konfigurationswerte aus Code in Umgebung oder Settings verschieben.
Ergebnis: