Sicherer PHP-Datei-Upload
Mittwoch, 10. Februar 2010 21:43
Kürzlich wurde eine meiner Websites von Islamisten gehackt. Vielleicht war es ja Osama bin Laden höchstpersönlich…
Bei den sechs aktuellsten Beiträgen war der Text durch eine Wiederholung der vielsagenden Textpassage “Hacked by Islamic Ghost Team” ersetzt worden.
Nachdem ich zuerst einige Stunden untätig vor mich hingeflucht habe, konnte ich doch einige Massnahmen einbauen, dank welchen ich nun wieder ruhig schlafen kann
Es gibt auf der Website einen Ort, wo man Bilder hochladen kann. Diese Bilder wurden nur auf den MIME-Type gecheckt, also in etwa so:
if($type == 'image/jpeg'){ /* korrektes Format */ }
Dieser MIME-Type mag ja ganz nützlich sein, um dem ehrlichen User mitzuteilen, dass er beispielsweise kein BMP- oder TIFF-Bild hochladen soll. Den gewitzten Hacker aber, der ein PHP-Skript einschleusen will, stört das nicht wirklich.
Deshalb habe ich noch folgende Zusatzmassnahmen eingebaut:
1. Im Uploadverzeichnis dürfen nur JPG, GIF und PNG-Dateien angezeigt werden. Alle anderen Dateien kriegen ein Forbidden. Dies macht folgdender Code im .htaccess
<filesmatch "\.+">
Order allow,Deny
Deny from All
</filesmatch>
<filesmatch "\.(jpg|png|gif)$">
Order allow,Deny
allow from All
Deny from None
</filesmatch>
2. Die Dateiendung habe ich ebenso analysiert, damit ein evil.php gar nicht erst hochgeladen wird:
$ext_orig = substr($_FILES['userfile']['name'], (strrpos($_FILES['userfile']['name'], '.')+1));
if(!in_array($ext_orig, array('jpg', 'png', 'gif'))){
echo 'FILE EXTENSION ERROR';
exit;
}
3. Damit man nicht ein PHP-Skript “evil.jpg” nennt und es nach dem Upload doch noch irgendwie auführen kann, habe ich noch eine Überprüfung eingebaut, um sicherzugehen, dass eine Upload-Datei wirklich ein Bild ist
$imgsize_orig = getimagesize($_FILES['userfile']['tmp_name']);
if($imgsize_orig === false || $imgsize_orig[0] < 5 || $imgsize_orig[1] < 5){
echo 'IMAGE SIZE NOT ACCEPTABLE';
exit;
}
Thema: Sicherheit | Kommentare (0) | Autor: admin