Sicherheits-Checkliste für das Hochladen von PHP-Bildern
Lesezeit: 7 Minuten
Ich programmiere ein Skript, um Bilder in meine Anwendung hochzuladen. Reichen die folgenden Sicherheitsschritte aus, um die Anwendung von der Skriptseite aus sicher zu machen?
Deaktivieren Sie die Ausführung von PHP innerhalb des Upload-Ordners mit .httaccess.
Hochladen nicht zulassen, wenn der Dateiname die Zeichenfolge „php“ enthält.
Nur Erweiterungen zulassen: jpg, jpeg, gif und png.
Nur Bilddateityp zulassen.
Bild mit zwei Dateitypen nicht zulassen.
Ändern Sie den Bildnamen.
Hochladen in ein Unterverzeichnis und nicht in das Stammverzeichnis.
Das ist mein Skript:
$filename=$_FILES['my_files']['name'];
$filetype=$_FILES['my_files']['type'];
$filename = strtolower($filename);
$filetype = strtolower($filetype);
//check if contain php and kill it
$pos = strpos($filename,'php');
if(!($pos === false)) {
die('error');
}
//get the file ext
$file_ext = strrchr($filename, '.');
//check if its allowed or not
$whitelist = array(".jpg",".jpeg",".gif",".png");
if (!(in_array($file_ext, $whitelist))) {
die('not allowed extension,please upload images only');
}
//check upload type
$pos = strpos($filetype,'image');
if($pos === false) {
die('error 1');
}
$imageinfo = getimagesize($_FILES['my_files']['tmp_name']);
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
die('error 2');
}
//check double file type (image with comment)
if(substr_count($filetype, "https://stackoverflow.com/")>1){
die('error 3')
}
// upload to upload direcory
$uploaddir="upload/".date("Y-m-d")."https://stackoverflow.com/" ;
if (file_exists($uploaddir)) {
} else {
mkdir( $uploaddir, 0777);
}
//change the image name
$uploadfile = $uploaddir . md5(basename($_FILES['my_files']['name'])).$file_ext;
if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
echo "<img id=\"upload_id\" src=\"".$uploadfile."\"><br />";
} else {
echo "error";
}
Neue Tipps sind willkommen 🙂
Ich würde die folgende Regel entfernen: Upload nicht zulassen, wenn der Dateiname die Zeichenfolge “php” enthält. Es wird nicht benötigt, da Sie die Datei umbenennen.
– troynt
12. November 2010 um 18:26 Uhr
Sie können herunterladen Sicheres Hochladen von Bildern von github. Es ist das sicherste lebende PHP-Skript. Es unterstützt auch die Größenänderung / das Zuschneiden von Bildern.
– Samayo
5. Dezember 2013 um 6:37 Uhr
@Alez Bei einem kurzen Blick auf diese Klasse ist die einzige Sicherheit, die ich sehen kann, eine Erweiterungsprüfung. Bitte, BITTE sagen Sie, dass es nicht so ist!
– sousdev
20. Januar 2014 um 17:39 Uhr
@Fricker So ist es nicht. In welchem Sinne? der pathinfo(, PATHINFO_EXTENSION) ist ein sehr zuverlässiger Weg, um die genaueste Dateierweiterung zu erhalten, eigentlich gibt es nichts Zuverlässigeres als das. lesen Sie, wo es steht “Hinweis”
– Samayo
20. Januar 2014 um 17:54 Uhr
@Alez ofc & btw Ich mag die Luke 3:11-Lizenz 🙂
– sousdev
22. Januar 2014 um 0:19 Uhr
Halil Özgür
Verarbeiten Sie das Bild erneut mit GD (oder Imagick) und speichern Sie das verarbeitete Bild. Alle anderen sind gerecht Spaß langweilig für Hacker.
Bearbeiten: Und wie rr betonte, verwenden Sie move_uploaded_file() für jeden Upload.
Late Edit: Übrigens, Sie sollten Ihren Upload-Ordner sehr einschränken. Diese Orte sind eine der dunklen Ecken, in denen viele Exploits passieren. Dies gilt für jede Art von Upload und jede Programmiersprache/jeden Server. Überprüfen https://www.owasp.org/index.php/Unrestricted_File_Upload
+1. Ich sehe nicht, wie eine der Prüfungen aus der Liste (in der Frage) nützlich sein kann, wenn es ist ein Bild und eine gültige Erweiterung enthält.
– Arseni Murzenko
12. November 2010 um 18:28 Uhr
Ich füge dies nicht hinzu, weil ich denke, dass es viel CPU-Verarbeitung benötigt.
– usef_ksa
12. November 2010 um 21:39 Uhr
Merken Sie sich meine Worte: Meistens ist die CPU die redundante Ressource. Sehen Sie sich einfach die Grafik eines bestimmten Computers / Servers an (mit Ausnahme von Google-, Facebook- usw. Servern vielleicht). Sie werden sehen, dass es dort die meiste Zeit staubt. Projekte wie SETI@Home versuchen, diese freie Zeit zu nutzen. Auf jeden Fall würde sich der Aufwand für das Plus an Sicherheit mehr als lohnen.
– Halil Özgür
12. November 2010 um 22:41 Uhr
Möchten Sie ein Beispiel für „Neubearbeitung“ nennen? Sagen wir mit imagick (oder schlimmer noch mit GD)?
– Andreas
2. Oktober 2013 um 11:54 Uhr
@ thorne51, ich glaube, keine Funktion reicht zum Überprüfen aus. Also einfach nicht prüfen, sondern einfach ein neues Image erstellen. Beispiel: PHP-Code kann in EXIF-, XMP- usw. Teilen des Bildes versteckt sein, und Funktionen/Programme können (versehentlich oder durch die Verwendung eines Exploit-Codes) diesen Code nicht melden.
– Halil Özgür
22. November 2013 um 12:55 Uhr
Für den Sicherheitstest der Bilddateien fallen mir 4 Sicherheitsstufen ein. Sie würden sein:
Level 1: Überprüfen Sie die Erweiterung (Erweiterungsdatei endet mit)
Stufe 2: Überprüfen Sie den MIME-Typ ($file_info = getimagesize($_FILES['image_file']; $file_mime = $file_info['mime'];)
Stufe 3: Lesen Sie die ersten 100 Bytes und prüfen Sie, ob sie Bytes im folgenden Bereich enthalten: ASCII 0-8, 12-31 (dezimal).
Hinweis: Das Laden des gesamten Bildes würde langsam sein.
3 & 4 werden nicht besonders langsam sein. Was langsam wäre, wäre das Laden des gesamten Bildes in eine Bibliothek, um es zu überprüfen.
– James Billingham
5. März 2014 um 11:23 Uhr
Rok Kralj
XSS-Warnung
Noch eine sehr wichtige Bemerkung. Stellen Sie nichts bereit/laden Sie nichts hoch, was im Browser als HTML interpretiert werden könnte.
Da sich die Dateien in Ihrer Domain befinden, hat das in diesem HTML-Dokument enthaltene Javascript Zugriff auf alle Ihre Cookies, wodurch eine Art XSS-Angriff ermöglicht wird.
Angriffsszenario:
Der Angreifer lädt eine HTML-Datei mit JS-Code hoch, die alle Cookies an seinen Server sendet.
Der Angreifer sendet den Link per E-Mail, PN oder einfach per Iframe auf seiner oder einer anderen Website an Ihre Benutzer.
Sicherste Lösung:
Machen Sie hochgeladene Inhalte nur auf der Subdomain oder auf der anderen Domain verfügbar. Auf diese Weise sind Cookies nicht zugänglich. Dies ist auch einer der Leistungstipps von Google:
Ich werde etwas wiederholen, das ich in verwandten Fragen gepostet habe.
Sie können den Inhaltstyp anhand von erkennen Fileinfo-Funktionen (mime_content_type() in früheren Versionen von PHP).
Ein Auszug aus dem PHP-Handbuch über die ältere Mimetype-Erweiterung, die jetzt durch Fileinfo ersetzt wird:
Die Funktionen in diesem Modul versuchen, den Inhaltstyp und die Kodierung einer Datei zu erraten, indem sie an bestimmten Positionen innerhalb der Datei nach bestimmten magischen Byte-Sequenzen suchen. Obwohl dies kein kugelsicherer Ansatz ist, leisten die verwendeten Heuristiken sehr gute Arbeit.
getimagesize() kann auch gute Arbeit leisten, aber die meisten anderen Überprüfungen, die Sie durchführen, sind Unsinn. Zum Beispiel warum string php ist im Dateinamen nicht erlaubt. Sie werden keine Bilddatei in ein PHP-Skript einfügen, nur weil ihr Name enthält php Saite, bist du?
Wenn es darum geht, Bilder neu zu erstellen, verbessert dies in den meisten Fällen die Sicherheit … bis die von Ihnen verwendete Bibliothek nicht anfällig ist.
Welche PHP-Erweiterung eignet sich also am besten für die sichere Image-Neuerstellung? Ich habe es überprüft CVE-Details Webseite. Ich denke, das anwendbare Trio sind diese Erweiterungen:
Aus dem Vergleich denke ich, dass GD am besten geeignet ist, weil es die geringste Anzahl von Sicherheitsproblemen hat und sie ziemlich alt sind. Drei davon sind kritisch, aber ImagMagick und Gmagick schneiden nicht besser ab… ImageMagick scheint sehr fehlerhaft zu sein (zumindest was die Sicherheit betrifft), also wähle ich Gmagick als zweite Option.
M Rostami
Wenn die Sicherheit sehr wichtig ist, verwenden Sie die Datenbank, um den Dateinamen zu speichern und den Dateinamen umzubenennen. Hier können Sie die Dateierweiterung in etwas wie .myfile ändern und eine PHP-Datei zum Senden von Bildern mit Headern erstellen. php kann sicherer sein und Sie können es im img-Tag wie blow verwenden:
Ich würde die folgende Regel entfernen: Upload nicht zulassen, wenn der Dateiname die Zeichenfolge “php” enthält. Es wird nicht benötigt, da Sie die Datei umbenennen.
– troynt
12. November 2010 um 18:26 Uhr
Sie können herunterladen Sicheres Hochladen von Bildern von github. Es ist das sicherste lebende PHP-Skript. Es unterstützt auch die Größenänderung / das Zuschneiden von Bildern.
– Samayo
5. Dezember 2013 um 6:37 Uhr
@Alez Bei einem kurzen Blick auf diese Klasse ist die einzige Sicherheit, die ich sehen kann, eine Erweiterungsprüfung. Bitte, BITTE sagen Sie, dass es nicht so ist!
– sousdev
20. Januar 2014 um 17:39 Uhr
@Fricker So ist es nicht. In welchem Sinne? der
pathinfo(, PATHINFO_EXTENSION)
ist ein sehr zuverlässiger Weg, um die genaueste Dateierweiterung zu erhalten, eigentlich gibt es nichts Zuverlässigeres als das. lesen Sie, wo es steht “Hinweis”– Samayo
20. Januar 2014 um 17:54 Uhr
@Alez ofc & btw Ich mag die Luke 3:11-Lizenz 🙂
– sousdev
22. Januar 2014 um 0:19 Uhr