Stoppen Sie Leute, die schädliche PHP-Dateien über Formulare hochladen

Ich habe ein Upload-Formular in PHP auf meiner Website erstellt, wo Menschen eine Zip-Datei hochladen können. Die ZIP-Datei wird dann extrahiert und alle Dateipositionen werden einer database hinzugefügt. Das Upload-Formular dient nur zum Hochladen von Bildern. Die Dateien befinden sich im Zip-Ordner. Ich kann nicht prüfen, welche Dateien hochgeladen werden, bis die Datei extrahiert wurde. Ich brauche einen Code, der alle Dateien löscht, die keine Bildformate sind (.png, .jpeg usw.). Ich bin wirklich besorgt darüber, dass Leute in der Lage sind, bösartige PHP-Dateien hochzuladen, großes Sicherheitsrisiko! Ich muss auch wissen, dass Leute die Erweiterungen von PHP-Dateien ändern, die versuchen, diese Sicherheitsfunktion zu umgehen.

Dies ist das ursprüngliche Skript, das ich verwendet habe http://net.tutsplus.com/videos/screencasts/how-to-open-zip-files-with-php/

Dies ist der Code, der die ZIP-Datei extrahiert:

function openZip($file_to_open) { global $target; $zip = new ZipArchive(); $x = $zip->open($file_to_open); if($x === true) { $zip->extractTo($target); $zip->close(); unlink($file_to_open); } else { die("There was a problem. Please try again!"); } } 

Danke, Ben.

   

Ich bin wirklich besorgt darüber, dass Leute in der Lage sind, bösartige PHP-Dateien hochzuladen, großes Sicherheitsrisiko!

Spitze des Eisbergs!

Ich muss auch bewusst sein, dass Leute die Erweiterungen von PHP-Dateien ändern, die versuchen, diese Sicherheitsfunktion zu umgehen.

Das Ändern der Erweiterungen hindert PHP daran, diese Dateien als Skripte zu interpretieren. Aber das ist nicht das einzige Problem. Es gibt mehr Dinge als ‘… php’, die die Server-Seite beschädigen können; “.htaccess” und Dateien mit dem X-Bit-Satz sind die offensichtlichen, aber keineswegs alles, worüber man sich Sorgen machen muss. Selbst wenn man das serverseitige Zeug ignoriert, gibt es ein großes clientseitiges Problem.

Wenn beispielsweise jemand eine “.html” -Datei hochladen kann, kann er ein

Dank des "Content-Sniffing" -Verhaltens einiger Browser (hauptsächlich IE) kann eine Datei, die als ".gif" hochgeladen wird, tatsächlich bösartiges HTML wie dieses enthalten. Wenn der IE in der Nähe des Dateianfangs Warnmeldungen wie (nicht beschränkt auf) "" sieht, kann er den bereitgestellten "Inhaltstyp" ignorieren und als HTML anzeigen, was zu XSS führt.

Darüber hinaus ist es möglich, eine Datei zu erstellen, die ein gültiges Bild ist, das von Ihrem Bildparser akzeptiert wird, und eingebettetes HTML enthält. Abhängig von der genauen Version des Browsers des Benutzers und dem genauen Format der Bilddatei gibt es verschiedene mögliche Ergebnisse (insbesondere JPEGs haben einen sehr variablen Satz möglicher Header-Formate). Es gibt Entschärfungen in IE8, aber das ist jetzt nicht sinnvoll, und Sie müssen sich fragen, warum sie nicht einfach aufhören können Content-Sniffing, Sie Idioten MS statt uns mit shonky nicht-Standard-Erweiterungen zu HTTP-Header, die haben sollte Gerade an erster Stelle gearbeitet.

Ich falle wieder in eine Tirade. Ich werde aufhören. Taktiken für die sichere Bereitstellung benutzerdefinierter Bilder:

1: Speichern Sie niemals eine Datei auf dem Dateisystem Ihres Servers mit einem Dateinamen, der von Benutzereingaben stammt. Dies verhindert sowohl Fehler als auch Angriffe: Verschiedene Dateisysteme haben unterschiedliche Regeln darüber, welche Zeichen in einem Dateinamen zulässig sind, und es ist viel schwieriger, als Sie vielleicht denken, Dateinamen zu bereinigen.

Selbst wenn Sie etwas sehr restriktives wie "nur ASCII-Buchstaben" genommen haben, müssen Sie sich immer noch um zu lange, zu kurze und reservierte Namen sorgen: versuchen Sie, eine Datei mit einem so harmlosen Namen wie "com.txt" auf einem zu speichern Windows-Server und beobachten Sie Ihre App untergehen. Denken Sie, dass Sie alle seltsamen Schwächen der Pfadnamen jedes Dateisystems kennen, auf dem Ihre App läuft? Zuversichtlich?

Speichern Sie stattdessen Dateidetails (z. B. Name und Medientyp) in der database und verwenden Sie den Primärschlüssel als Namen in Ihrem Dateispeicher (z. B. "74293.dat"). Sie müssen dann einen Weg finden, sie mit verschiedenen scheinbaren Dateinamen zu versehen, wie zum Beispiel ein Downloader-Skript, das die Datei ausspuckt, ein Downloader-Skript, das eine interne Umleitung des Web-Servers ausführt, oder URL-Umschreiben.

2: Sei sehr, sehr vorsichtig mit ZipArchive. Es gab Traversal- Sicherheitslücken in extractTo der gleichen Art, die die meisten naiven pfadbasierten ZIP-Extraktoren beeinflusst haben. Außerdem legst du dich offen gegen Zip-Bomben anzugreifen . Am besten vermeiden Sie die Gefahr eines schlechten Dateinamens, indem Sie jeden Dateieintrag im Archiv durchlaufen (z. B. mit zip_read / zip_entry_ * ) und die Details prüfen, bevor Sie den Stream manuell in eine Datei mit bekannten Namen und Modus-Flags entpacken generiert ohne die Hilfe des Archivs. Ignoriere die Ordnerpfade in der ZIP-Datei.

3: Wenn Sie eine Bilddatei laden und sie wieder speichern können , insbesondere wenn Sie sie zwischendurch bearbeiten (z. B. Größenänderung / Miniaturansicht oder Hinzufügen eines Wasserzeichens), können Sie sicher sein, dass die Ergebnisse angezeigt werden reinigen. Theoretisch könnte es möglich sein, ein Bild zu machen, das auf einen bestimmten Bildkompressor abzielt, so dass die Ergebnisse beim Komprimieren auch wie HTML aussehen würden, aber das scheint für mich ein sehr schwieriger Angriff zu sein.

4: Wenn es Ihnen gelingt, alle Ihre Bilder als Download zu versenden (zB mit "Content-Disposition: Anhang" in einem Downloader-Skript), sind Sie wahrscheinlich in Sicherheit. Aber das könnte für die Benutzer zu viel Unannehmlichkeit sein. Dies kann zusammen mit (3) funktionieren, indem kleinere, verarbeitete Bilder inline bereitgestellt werden und die ursprünglichen Bilder in höherer Qualität nur als Download zur Verfügung stehen.

5: Wenn Sie inline unveränderte Images bereitstellen müssen, können Sie das Cross-Site-Scripting-Risiko entfernen, indem Sie sie aus einer anderen Domäne bereitstellen. Verwenden Sie beispielsweise 'images.example.com' für nicht vertrauenswürdige Bilder und 'www.example.com' für die Hauptseite, die die gesamte Logik enthält. Stellen Sie sicher, dass Cookies nur auf den richtigen virtuellen Host beschränkt sind und dass die virtuellen Hosts so eingerichtet sind, dass sie nur auf ihre Eigennamen reagieren können (siehe auch: DNS-Rebind-Angriffe). Das machen viele Webmail-Dienste.

Zusammenfassend ist festzuhalten, dass vom Nutzer übermittelte Medieninhalte ein Problem darstellen.

Zusammenfassung der Zusammenfassung, AAAARRRRRRRGGGGHHH.

ETA re kommentieren:

ganz oben hast du von 'Dateien mit dem X-Bit-Set' gesprochen, was meinst du damit?

Ich kann nicht für ZipArchive.extractTo() sprechen, da ich es nicht getestet habe, aber viele Extraktoren erstellen, wenn sie aufgefordert werden, Dateien aus einem Archiv zu ZipArchive.extractTo() , einige der Unix-Dateimodus-Flags, die jeder Datei zugeordnet sind Das Archiv wurde auf einem Unix erstellt und hat daher tatsächlich Mode-Flags. Dies kann zu Berechtigungsproblemen führen, wenn beispielsweise die Leseberechtigung des Besitzers fehlt. Es kann aber auch ein Sicherheitsproblem sein, wenn Ihr Server CGI-fähig ist: Ein X-Bit kann erlauben, dass die Datei als Skript interpretiert und an einen Skript-Interpreter übergeben wird, der in der ersten Zeile im Hashbang aufgeführt ist.

Ich dachte, dass .htaccess im Hauptstammverzeichnis sein müsste, ist das nicht der Fall?

Hängt davon ab, wie Apache eingerichtet ist, insbesondere die AllowOverride-Direktive. Es ist üblich, dass Allzweck-Hosts AllowOverride für ein beliebiges Verzeichnis verwenden.

Was würde passieren, wenn jemand noch eine Datei wie ../var/www/wr_dir/evil.php hochladen würde?

Ich würde erwarten, dass das führende ".." weggeworfen wird. Das ist es, was andere Tools, die die gleiche Schwachstelle erlitten haben, getan haben.

Aber ich würde extractTo() gegenüber feindseligen Eingaben immer noch nicht vertrauen, da es zu viele seltsame kleine Dateien / Verzeichnisbaum-Dinge gibt, die schief gehen können - besonders wenn Sie erwarten, dass sie jemals auf Windows-Servern laufen. zip_read() gibt Ihnen viel mehr Kontrolle über den Dearchivierungsprozess und somit den Angreifer viel weniger.

Zuerst sollten Sie jede Datei verbieten, die keine richtige Bilddateierweiterung hat. getimagesize können Sie mit der function getimagesize überprüfen, ob es sich bei den Dateien um normale Bilddateien handelt.

Außerdem sollten Sie beachten, dass einige Bildformate Kommentare und andere Metainformationen erlauben. Dies könnte für bösartigen Code wie JavaScript verwendet werden, den einige Browser unter bestimmten Umständen ausführen (siehe Riskantes MIME-Sniffing in Internet Explorer ).

Sie sollten sich dann wahrscheinlich nicht nur auf die Dateinamenserweiterung verlassen. Versuchen Sie, jede Datei durch eine Bildbibliothek zu übertragen, um zu bestätigen, dass es auch wirklich ein Bild ist.

Ich sehe nicht das Risiko, dass PHP-Dateien in Ihrer DB umbenannt werden … Solange Sie sie nicht als PHP-Dateien bewerten (oder überhaupt, überhaupt), können sie nicht zu viel Schaden anrichten, und Da es keine .php-Erweiterung gibt, wird die php-Engine sie nicht berühren.

Ich denke du könntest auch die Dateien nach < ?php durchsuchen ...

Außerdem : nehmen Sie das Schlimmste an den Dateien an, die auf Ihren Computer hochgeladen wurden. Umbenennung des Ordners, in den Sie sie speichern, "Viren" und entsprechend behandeln. Mach es nicht öffentlich, gib keine Dateistartberechtigungen (insbesondere den PHP-Benutzer) usw.

Vielleicht möchten Sie auch die Mime-Typ-Erkennung mit der folgenden Bibliothek durchführen:

http://ca.php.net/manual/de/ref.fileinfo.php

Jetzt verlassen Sie sich auf Ihren Festplattenplatz zum Extrahieren. Sie können Dateiheader überprüfen, um festzustellen, um welche Art von Dateien es sich handelt. da gibt es wohl Bibliotheken dafür.

offtopic: Ist es nicht besser, den Benutzer einige Bilder auswählen zu lassen, anstatt eine Zip-Datei hochzuladen? Besser für Leute, die nicht wissen was Zip ist (ja, sie existieren)

Wenn Sie php so einstellen, dass nur Dateien mit der Endung .php analysiert werden, können Sie einfach eine Datei von somename.php in somename.php.jpeg umbenennen und Sie sind sicher.

Wenn Sie wirklich die Dateien löschen möchten, gibt es eine Zip-Bibliothek für PHP. Sie können damit die Namen und Erweiterungen aller Dateien im hochgeladenen Zip-Archiv überprüfen und dem Benutzer eine Fehlermeldung geben, wenn er eine PHP-Datei enthält.

Persönlich würde ich etwas zur Apache-Konfiguration hinzufügen, um sicherzustellen, dass es PHP-Dateien als Text von dem Ort, an den die Dateien hochgeladen werden, versorgt, damit Sie sicher sind und andere Dateitypen in Zukunft hochgeladen werden können.

Beware dieser Weitergabe bösartiger PHP durch getimagesize ()

injizieren Sie PHP über Bildfunktionen, die mithilfe der function getimagesize () sicherstellen, dass Bilder sicher sind

Lesen Sie hier mehr http://ha.ckers.org/blog/20070604/passing-malicious-php-through-getimagesize/

Besser für Ihr Benutzerlogo verwenden Sie gravatar wie hier von Stackoverflow;)

Verwenden Sie die Getimagesize-function. Vollständige Prozedur: – 1.) Extrahiere die Erweiterung des Bildes / der hochgeladenen Datei und vergleiche dann die Erweiterung mit der erlaubten Erweiterung. 2.) Erstellen Sie nun eine zufällige Zeichenfolge zum Umbenennen der hochgeladenen Datei. Die beste Idee ist md5(session_id().microtime()) kann nicht dupliziert werden und wenn Ihr Server sehr schnell ist und weniger als eine Mikrosekunde verarbeiten kann, als inkrementierte Variable verwenden und sie mit string hinzufügen. Verschieben Sie diese Datei jetzt.

Ein Tipp Deaktivieren Sie die PHP-Dateiverarbeitung im Upload-Verzeichnis, es wird Sie immer vor einem Server-Angriff schützen und wenn möglich, fügen Sie Ihren htaccess im Root-Verzeichnis oder in der httpd-Konfigurationsdatei hinzu und deaktivieren Sie htaccess-Dateien von dort jetzt lösen Sie Ihre maximalen Probleme