KayTwo: Hilfe bei Image Upload!

Guten Morgen,

ich bräuchte mal wieder die Hilfe der Community hier..

Und zwar möchte ich jetzt auf meiner Website einen Image-Upload implementieren.

Wie stelle ich es also an, dass die Datei die hochgeladen wird auf mehr als nur die File-Extension überprüft wird, um sicher zu gehen dass es sich wirklich um ein Bild handelt und nicht um eine PHP-Shell oder etwaiges?

Mit freundlichen Grüßen, KayTwo (Kay2)

  1. Tach!

    Wie stelle ich es also an, dass die Datei die hochgeladen wird auf mehr als nur die File-Extension überprüft wird,

    Indem du in deinem Code mehrere Bedingungen testest. Das hat nichts mit dem Upload zu tun, sondern ist ein ganz normaler Programmieralltag unter Verwendung von if zusammen mit and und/oder or. Was ist denn das genaue Problem?

    um sicher zu gehen dass es sich wirklich um ein Bild handelt und nicht um eine PHP-Shell oder etwaiges?

    Allein an der Dateiendung kann man nicht erkennen, ob im Inhalt ungewünschtes Zeug steckt. Man kann damit lediglich die Annahme von Endungen verweigern, bei denen der Webserver sonst eine Aktion unternimmt (beispielsweise Ausführen).

    dedlfix.

  2. Guten Morgen KayTwo,

    du könntest den MIME-Type prüfen. Da hat die PHP-Dokumentation eine sehr gute Erklärung zu. Hier ein kleiner Auszug:

        $finfo = new finfo(FILEINFO_MIME_TYPE);
        if (false === $ext = array_search(
            $finfo->file($_FILES['upfile']['tmp_name']),
            array(
                'jpg' => 'image/jpeg',
                'png' => 'image/png',
                'gif' => 'image/gif',
            ),
            true
        )) {
            throw new RuntimeException('Invalid file format.');
        }
    

    Freundliche Grüße
    Christian

    1. Tach!

      du könntest den MIME-Type prüfen.

      Kann man, aber das ist jetzt auch nur ein bisschen sicherer als so eine Dateiendungsprüfung. Zur Ermittlung des MIME-Types schaut die Funktion lediglich nach ein paar wenigen Magic Bytes, ob diese an den für diesen Dateityp typischen Stellen zu finden sind. Es wird nicht geprüft, ob der Rest vom Inhalt den Regeln für dieses Dateiformat entspricht, und auch nicht, ob sich eventuell in irgendwelchen Kommentar-/Freitext-Feldern Schadcode befindet. Die MIME-Type-Prüfung kann man vornehmen, aber man sollte wissen, was man damit erreichen kann und was prinzipbedingt nicht zu leisten geht.

      dedlfix.

      1. Hallo dedlfix,

        danke für die Information, daran hatte ich nicht gedacht. Das macht die Sache dann natürlich wieder etwas komplizierter...

        Freundliche Grüße
        Christian

  3. Viele gehen so vor:

    Aus $_FILES['file']['tmp_name'] je nach ermittelten (nicht: übertragenen) MimeType mit:

    • imagecreatefromgif() oder
    • imagecreatefromjpg() oder
    • imagecreatefrompng() oder
    • imagecreatefrombmp() oder
    • imagecreatefromwebp() oder

    die "Arbeitskopie" für PHP erzeugen. Dann mit

    • imagesx() und
    • imagesy()

    Breite und Höhe feststellen.

    Mit diesen Daten und

    • imagecreatetruecolor() sowie
    • imagecopy()

    ein neues Bild erstellen und je nach Wunsch mit

    • imagegif() oder
    • imagejpeg() oder
    • imagepng() oder
    • imagewbmp() oder
    • imagewpng() oder
    • imagewebp()

    in die Zieldatei wegschreiben.

    Klappt etwas von den ersten Gruppe nicht, so ist es kein bmb, gif, jpeg, png oder webp. Also falls Du nicht selbst irgendwas falsch gemacht hast.

    ##Wichtig:##

    • Bei heise.de täglich nachschauen, ob imagecreatefrom* als fehlerhaft und angreifbar gemeldet wird. Und PHP regelmäßig updaten...
    1. Hallo,

      Viele gehen so vor:

      ich kann mir nicht vorstellen, dass es "viele" sind. Die Methode hat nämlich durchaus auch Nachteile.

      Aus $_FILES['file']['tmp_name'] je nach ermittelten (nicht: übertragenen) MimeType mit:

      • imagecreatefromfoo()
        die "Arbeitskopie" für PHP erzeugen. Dann mit
      • imagesx() und imagesy()
        Breite und Höhe feststellen.

      Mit diesen Daten und

      • imagecreatetruecolor() sowie imagecopy()
        ein neues Bild erstellen und je nach Wunsch mit
      • imagefoo()
        in die Zieldatei wegschreiben.

      Sollte das hochgeladene Bild ein JPEG sein, ergibt sich durch die Neukomprimierung beim Speichern ein möglicherweise relevanter Qualitätsverlust (webp möglicherweise auch). Ein eventuell vorhandenes Wasserzeichen wird dabei auch in Mitleidenschaft gezogen.

      Für alle Formate gilt: Eventuell vorhandene Metadaten (ich denke da vor allem an EXIF) sind danach auch weg. Das möchte man aber vielleicht nicht.

      So long,
       Martin

      --
      Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
      - Douglas Adams, The Hitchhiker's Guide To The Galaxy
    2. Viele gehen so vor

      Oder sie benutzen gleich ImageMagick, so wie ich. Ich habe mir dann eien Klasse drumherum geschrieben, sodaß ich IM aus jedem meiner Scripte noch bequemer nutzen kann.

      Lukas

  4. Hallo und guten Abend,

    Und zwar möchte ich jetzt auf meiner Website einen Image-Upload implementieren.

    Wie stelle ich es also an, dass die Datei die hochgeladen wird auf mehr als nur die File-Extension überprüft wird, um sicher zu gehen dass es sich wirklich um ein Bild handelt und nicht um eine PHP-Shell oder etwaiges?

    Lies dir auf jeden Fall die Gedanken dazu im Wiki durch, auch wenn sie nicht vollständig sind: File-Upload mit PHP

    Das betrifft zwar gezielt PHP, reißt aber schon eine Menge der möglichen Fehlerquellen an.

    Grüße
    TS

    --
    es wachse der Freifunk
    http://freifunk-oberharz.de