Zum Inhalt springen
DedicatedPHP Kontakt

Sicherer Datei-Upload in PHP: Ende-zu-Ende-Design

Entwerfen Sie einen Datei-Upload in PHP mit echter Validierung, Quarantäne, Download-Berechtigungen, Nachvollziehbarkeit und Wiederherstellungstests.

Redaktionelles Diagramm eines sicheren Datei-Upload-Ablaufs in PHP, vom Empfang und der Quarantäne bis zum autorisierten Download

Ein sicherer Datei-Upload in PHP bedeutet nicht, ein Formular anzunehmen und eine Datei auf den Server zu verschieben. Ein Anhang kann zu einem Ausführungsvektor, einem Informationsleck, einer ressourcenerschöpfenden Last oder zu einem nicht zugänglichen Dokument werden, wenn der Geschäftsprozess ihn benötigt. Das Design muss den gesamten Lebenszyklus abdecken: Empfang, Validierung, Speicherung, Verarbeitung, Zugriffsautorisierung, Auditierung und Löschung.

Den Geschäftsvertrag definieren, bevor Dateien angenommen werden

Den Geschäftsvertrag definieren, bevor Dateien angenommen werden — guía visual de DedicatedPHP

Die erste Kontrolle ist nicht technisch: Es muss festgelegt werden, welchen Bedarf jeder Anhang abdeckt. Ein Identitätsnachweis, eine Rechnung und ein Profilbild haben unterschiedliche Formate, Eigentümer, Aufbewahrungsfristen und Zugriffsberechtigungen. Sie unter einer generischen Option wie „Datei hochladen“ zusammenzufassen, erschwert die Anwendung angemessener Kontrollen.

Definieren Sie für jeden Dokumenttyp einen expliziten Vertrag:

  • Welche Formate erforderlich sind und welche ausgeschlossen werden.
  • Maximale Größe, maximale Anzahl von Anhängen pro Vorgang und kumuliertes Kontingent pro Konto oder Fallakte.
  • Wer sie hochladen darf, in welchem Prozessstatus und ob sie ersetzt oder gelöscht werden können.
  • Welche automatische Validierung und welche menschliche Prüfung erforderlich sind.
  • Wer sie ansehen, herunterladen oder eine neue Version anfordern darf.
  • Wie lange sie aufbewahrt werden und welches Ereignis ihre Löschung auslöst.

Dieser Vertrag verhindert, Dateien „für alle Fälle“ anzunehmen. Er ermöglicht außerdem, zwischen einem Validierungsfehler, den der Benutzer korrigieren kann, und einer Geschäftsrestriktion zu unterscheiden, etwa dem Versuch, ein Dokument anzuhängen, wenn die Fallakte bereits abgeschlossen ist.

Warum Dateiendung und deklarierter Typ nicht ausreichen

Die Dateiendung des ursprünglichen Namens und der in $_FILES['type'] gesendete Typ sind vom Client bereitgestellte Daten. Sie dienen als ergänzende Informationen für die Benutzeroberfläche, beweisen jedoch nicht den Inhalt. Eine Datei umzubenennen ist trivial, und ein Client kann beliebige HTTP-Header senden.

Die technische Validierung muss eine mehrschichtige Verteidigung verwenden. Ermitteln Sie in PHP den Typ anhand der empfangenen Bytes mit Mechanismen wie finfo; wenden Sie anschließend formatbezogene Validatoren an, wenn Risiko oder Nutzung dies erfordern. Bei einem Bild, das angezeigt werden soll, reicht es nicht aus, es als Bild zu identifizieren: Es ist ratsam, es mit einer geeigneten Bibliothek zu dekodieren und eine neue Darstellung zu erzeugen. Validieren Sie bei einer PDF-Datei oder einem Office-Dokument die erwartete Struktur mit spezialisierten Werkzeugen in einer isolierten Umgebung.

Eine Allowlist ist sicherer als eine Blocklist. Wenn der Anwendungsfall JPEG und PNG zulässt, lehnen Sie alles andere ab, statt zu versuchen, gefährliche Formate aufzuzählen. Komprimierte Dateien erfordern eine zusätzliche Kontrolle: Eine Begrenzung der komprimierten Größe begrenzt die Expansion beim Dekomprimieren nicht. Legen Sie Obergrenzen für entpackte Größe, Anzahl der Einträge, Verschachtelungstiefe und Analysedauer fest.

Auch Namen sind nicht vertrauenswürdig. Verwenden Sie sie weder als Pfad noch als Kennung oder physischen Namen. Sequenzen wie ../, Steuerzeichen, doppelte Erweiterungen und Namenskollisionen müssen an Bedeutung verlieren, weil das System eine eigene undurchsichtige Kennung erzeugt.

Kontrollierter Empfang und Umgang mit Teilfehlern

Begrenzen Sie die Eingangsfläche, bevor Sie den Inhalt verarbeiten. Konfigurieren Sie konsistente Limits in PHP, dem Webserver und dem Reverse Proxy. Wenn der Proxy 100 MB akzeptiert, PHP jedoch 10 MB zulässt, wird das Verhalten verwirrend; wenn PHP mehr als vorgesehen erlaubt, kann ein Angreifer Arbeitsspeicher, temporären Speicherplatz oder Arbeitsverbindungen verbrauchen.

Kontrollieren Sie explizit die Einzelgröße, die Gesamtgröße der Anfrage, die Anzahl der Dateien und die Upload-Dauer. Prüfen Sie den Fehlercode jedes Eintrags in $_FILES, verifizieren Sie, dass er aus einem HTTP-Upload stammt, und behandeln Sie jeden Anhang als eigenständige Einheit. Entscheiden Sie bei einem Mehrfachvorgang im Voraus, ob das Ergebnis atomar oder teilweise ist. Wenn Teilergebnisse akzeptiert werden, muss die Antwort präzise angeben, welche Datei empfangen, welche abgelehnt wurde und warum, ohne interne Serverdetails offenzulegen.

Verarbeiten Sie eine Datei nicht direkt über einen durch die Anfrage gesteuerten Pfad und verlassen Sie sich nicht darauf, dass ein unterbrochener Upload unschädlich ist. Unvollständige temporäre Dateien müssen bereinigt werden, und Wiederholungen müssen idempotent sein, wenn das Produkt sie unterstützt. Ein Vorgangs-Token oder ein Idempotenzschlüssel verhindert, dass nach erneuten Netzwerkübertragungen mehrere gleichwertige Anhänge erstellt werden.

Private Speicherung, Quarantäne und Verarbeitung

Binärdateien dürfen nicht im öffentlichen Verzeichnis der Anwendung liegen. Speichern Sie sie in privatem Storage mit Zugangsdaten nach dem Prinzip minimaler Berechtigungen und ordnen Sie jedes Objekt einer vom System generierten internen Kennung zu. Die Datenbank kann Metadaten wie Eigentümer, Geschäftskontext, erkannten Typ, Größe, kryptografischen Fingerabdruck, Status, Zeitstempel und Aufbewahrungsrichtlinie enthalten. Vermeiden Sie, unnötige personenbezogene Daten im Namen oder in Betriebsprotokollen zu speichern.

Ein robuster Ablauf trennt Empfang und Verfügbarkeit:

  1. Die Anwendung empfängt die Datei und erstellt einen Datensatz im Status pendiente oder en_cuarentena.
  2. Die Binärdatei wird an einem Ort abgelegt, der für Downloads nicht zugänglich ist.
  3. Eine asynchrone Verarbeitungskomponente führt eine Malware-Analyse, eine tiefgehende Validierung, Transformation oder zulässige Extraktion durch.
  4. Das Ergebnis wechselt zu disponible, rechazado oder requiere_revision.
  5. Die Benutzeroberfläche zeigt den Betriebsstatus an, ohne vorzutäuschen, dass ein Upload bereits nutzbar ist.

Warteschlangen verkürzen die Antwortzeit, bringen jedoch eigene Fehler mit sich: doppelte Jobs, verzögerte Nachrichten und ausgefallene Worker. Entwerfen Sie idempotente Tasks, Wiederholungslimits, Warnmeldungen für feststeckende Elemente und einen kontrollierten Weg zur Wiederverarbeitung. Wenn die Analyse nicht verfügbar ist, besteht die sichere Alternative in der Regel darin, den Anhang in Quarantäne zu halten und ihn nicht zu veröffentlichen.

Jeden Download autorisieren und Inhalte ohne Ausführung bereitstellen

Dass jemand eine Kennung kennt, gewährt keinen Zugriff. Bei jedem Download müssen die authentifizierte Identität, ihre aktuelle Beziehung zur Ressource und der Geschäftskontext geprüft werden: Zugehörigkeit zu einer Organisation, Zuordnung zur Fallakte, aktuelle Rolle, Dokumentstatus und zeitliche Einschränkungen. Verwenden Sie nicht erneut die Autorisierung, die beim Hochladen der Datei bestand; Berechtigungen können danach widerrufen worden sein.

Der Download muss über einen Controller erfolgen, der diese Entscheidung anwendet, bevor er das Objekt liest oder dessen Bereitstellung delegiert. Signierte URLs können für die Auslieferung aus externem Storage nützlich sein, erfordern jedoch einen begrenzten Geltungsbereich, kurze Ablaufzeiten und Kontrollen, die verhindern, dass sie für nicht autorisierte Ressourcen ausgestellt werden.

Stellen Sie aktive Typen mit Vorsicht bereit. Verwenden Sie für Dokumente, die nicht im Browser gerendert werden sollen, Content-Disposition: attachment. Legen Sie den Content-Type anhand des validierten Typs fest, nicht anhand der Erweiterung, und fügen Sie X-Content-Type-Options: nosniff hinzu. Eine Vorschau ist kein einfacher eingebetteter Download: Sie muss transformierte Darstellungen verwenden, potenziell aktive Inhalte isolieren und die Offenlegung interner Pfade vermeiden.

Auditierung, Wiederherstellung und Tests vor der Produktion

Auditierung, Wiederherstellung und Tests vor der Produktion — guía visual de DedicatedPHP

Protokollieren Sie relevante Ereignisse: Erstellung, Ersetzung, Statusänderung, Download, Löschung, Analysefehler und Änderung von Berechtigungen. Das Protokoll muss Akteur, Zeitpunkt, Ressource und Ergebnis enthalten, muss jedoch weder die Binärdatei noch doppelte sensible Daten speichern. Schützen Sie diese Ereignisse vor Veränderungen und definieren Sie, wer sie einsehen darf.

Wiederherstellung erfordert zu wissen, was geschieht, wenn Storage, Datenbank oder die Verarbeitungskomponente ausfallen. Markieren Sie ein Dokument nicht als verfügbar, bevor Binärdatei und Metadaten konsistent sind. Entwerfen Sie Abgleich-Tasks, um Datensätze ohne Objekt, verwaiste Objekte und Elemente zu erkennen, die zu lange in Quarantäne verbleiben.

Checkliste für die Freigabe

  • Die erlaubten Formate entsprechen einem dokumentierten Anwendungsfall und werden nach Inhalt validiert.
  • Es gibt Limits für Größe, Menge, Zeit und Expansion komprimierter Dateien.
  • Die ursprünglichen Namen bestimmen weder Pfade noch physische Namen.
  • Die Binärdateien werden außerhalb des öffentlichen Verzeichnisses gespeichert und durchlaufen gegebenenfalls eine Quarantäne.
  • Der Download bewertet die Autorisierung erneut und legt keine internen Pfade offen.
  • Fehlformatierte Dateien, Duplikate, unterbrochene Uploads, widerrufene Berechtigungen und Storage-Ausfälle werden getestet.
  • Es gibt Monitoring für Ablehnungen, feststeckende Jobs, Auslieferungsfehler und verbrauchte Kapazität.
  • Für Aufbewahrungs-, Lösch- und Auditierungsrichtlinien gibt es einen operativen Verantwortlichen.

Aus einem Upload einen Ablauf mit Zuständen und Kontrollen zu machen, kann kostspieliger erscheinen als ein Upload-Verzeichnis zu verwenden. Es reduziert jedoch improvisierte Entscheidungen, wenn eine verdächtige Datei, eine Zugriffsanfrage oder eine Betriebsunterbrechung auftritt. Diese Nachvollziehbarkeit ist Teil des Produkts und kein nachträglicher Zusatz.

Möchten Sie diese Ideen in Ihrem Projekt anwenden?Lass uns über deine PHP-Plattform sprechen.
Verwandten Dienst anzeigen