Sicherer Dateiupload: Worauf ist zu achten?

Hallo,

ich bin gerade dabei, einen Dateiupload in PHP zu programmieren. Das ganze funktioniert über ein normales Formular, die Datei wird auf dem Server in einem geschützten Verzeichnis abgespeichert. Als Administrator kann ich im Administrationsbereich selbst bestimmen, welche Dateitypen ich zulassen will.

Allerdings habe ich den Sicherheitsaspekt noch nicht bedacht. Solche Uploads sind in der Regel ja nicht ganz ungefährlich, hört man doch immer wieder mal, dass Code eingeschleust werden konnte. Zurzeit prüfe ich einfach bei jedem Upload, ob die Dateiendung erlaubt ist oder nicht, wobei Geschichten wie *.php oder *.php3 etc. von Vornherein blockiert werden. Ich glaube aber nicht, dass ich mich einfach auf die Dateiendung verlassen kann, diese kann der Benutzer ja jederzeit problemlos ändern. Deswegen meine Frage: Worauf ist bei einem Uploadformular bezüglich Security noch zu achten, ausser auf die Endung?

Was soll denn mit den Dateien nach dem Upload gemacht werden? Werden die von dir irgendwann aufgerufen oder ausgeführt? Wenn die Daten einfach nur abgelegt werden sollte es egal sein, welchen Inhalt sie haben.

Ansonsten kann ich dir die Seite von Peter Kropff empfehlen, die hierzu einen guten Artikel anbietet:
http://www.peterkropff.de/allgemeines/sicher_programmieren/dateiuploads_1.htm

Die Dateien werden erstmal nur abgelegt. Sind es Bilder, werden aber noch verschiedene Versionen wie z. B. Thumbnail und ein kleineres Format erzeugt, und diese sind dann sofort öffentlich.

Ausgeführt werden die Dateien nicht, die sollen im Grundsatz später nur zum Download bereitgestellt werden. Wie auch schon angesprochen, lasse ich vom PHP-Interpreter ausführbare Formate wie *.php gar nicht erst zu. Was ich möchte, ist einfach, den Upload soweit abzusichern, dass es nicht mehr möglich ist, fremden PHP-Code irgendwie auf dem Server auszuführen.

Also sobald Bilder hochgeladen und angezeigt werden sollen. Solltest du aufjedenfall überprüfen ob es sich wirklich um Bilder handelt. Weil wenn jemand eine .jpg im Texteditor erzeugt, dort Javascript Code reinschreibt und dann hochlädt wird dieser Code jedesmal ausgeführt wenn die Seite mit dem Bild geöffnet wird.

Das kannst du überprüfen, indem du z.b. mit getimagesize() versuchst dir die Bildgröße der jpg-Datei anzeigen zu lassen.

Was an den PHP-Interpreter geschickt wird, wird in der Webserver-Konfiguration festgelegt. Hier findet man meist die Dateiendungen php, php4, php5 etc. Zur zuverlässigen Verhinderung der Ausführung hochgeladener Files als PHP ist darum die Prüfung der Endung ausreichend. Auch wenn ein Nutzer eine Datei mit Endung txt hochlädt, die in Wirklichkeit php-Code enthält, würde der Webserver garnicht auf die Idee kommen, sie an den Interpreter weiter zu reichen. Du wirst ja nicht eine der hochgeladenen Dateien mit include oder so ein binden oder?

Unter Garantie nicht. Ich habe mich nur gefragt, ob es da auch noch andere Methoden gibt, um PHP-Code einzuschleusen und auszuführen, und vor allem, wie ich das als Entwickler verhindern kann.

Ich werde einmal versuchen, die Liste mit den Endungen aus der Konfigurationsdatei auszulesen und diese dann automatisch zu blockieren. Wobei mein System grundsätzlich schon ein Whitelist-System ist, also dass der Administrator Endungen explizit erlauben muss.

Es muss ja keine hochgeladene Datei sein, die eingebunden wird. Wenn ggf. ein include mit einem Parameter, der vom Nutzer eingegeben wurde, versehen ist, dann könnte es eine directory-traversal-Lücke geben.

Edit, Beispiel:

include 'includes/' . $_GET['classname'] . '.php';

Damit ließe sich dann hochgeladener Code ausführen. Dazu muss aber einiges zusammenkommen. Allein durch hochgeladene Dateien ist eine Webseite nicht angreifbar, es muss immer eine weitere Lücke hinzukommen (ok, es sei denn, die hochgeladenen Dateien sind per URL abrufbar und sie werden mit dem vom Nutzer angegebenen Dateinamen abgespeichert. Aber das ist dann so … ungeschickt … dass man selbst schuld ist…).

Wenn du mit Datei-Uploads arbeitest, sind folgende Funktionen sicherlich interessant


move_uploaded_file();
is_uploaded_file();

Welches Framework?

nicht direkt - da müssen zumindest Bufferoverflows in PHP bzw. dem Webserver existieren. Komplexer wirds dann noch wenn weitere Dinge mit externen Librarys/Programmen auf dem Server ausgeführt werden. Auch hier ist über Bufferoverflows möglich im Bild Code unterzuschummeln der dann auf dem Server ausgeführt wird.

Aber dagegen kann man nichts machen, außer immer die aktuellesten Versionen verwenden.