Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Upload - Prüfung Dateityp

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • #16
    Eine Möglichkeit wäre, den Bilder-Ordner tatsächlich ausserhalb von Webroot zu platzieren und im HTML-Quellcode über eine "Controller"-Datei zu holen:
    Code:
    <img src="./get-image.php?imagename=foo.jpg" alt="" />
    PHP-Code:
    // get-image.php
    header 'Content-Type: image/jpeg' );

    $sImagesFolder '/var/www/vhosts/example.com/images/';
    $bIsValidRequest = isset($_GET['imagename']) && file_exists$sImagesFolder $_GET['imagename'] );

    if ( 
    $bIsValidRequest ) {

        echo 
    file_get_contents$sImagesFolder $_GET['imagename'] );


    Wobei das sicher nicht Dein Anliegen löst, denn ich denke, wenn es Dir darum geht, Schadcode durch Bilder zu unterbinden, wirst Du da nie auf Nummer sicher sein, solange Du sie auf irgendeine Weise in der Website anzeigen möchtest.
    Competence-Center -> Enjoy the Informatrix
    PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

    Kommentar


    • #17
      Wobei das sicher nicht Dein Anliegen löst, denn ich denke, wenn es Dir darum geht, Schadcode durch Bilder zu unterbinden, wirst Du da nie auf Nummer sicher sein, solange Du sie auf irgendeine Weise in der Website anzeigen möchtest.
      ja, denke ich auch. Ich denke, das jetzige Konstrukt bietet zwar keine absolute, aber einiges an Sicherheit:
      1. Upload findet nur im passwortschützten Adminbereich (also nur Bearbeiter des CMS) statt.
      2. Die Dateiprüfungen wie gepostet (für PDF, Word, Excel usw. hier am Anfang des Threads; für Bilder hier: http://www.php.de/php-einsteiger/113...n-bildern.html
      3. in den Bilder-/Dokument-Ordnern ist die php engine ausgeschaltet

      Danke für alle Hinweise! Damit kann ich den Thread wohl schließen, oder...?

      Kommentar


      • #18
        Zitat von HeinrichK Beitrag anzeigen
        Die Bilder sollen in der Webseite angezeigt werden. Also treffen wohl die Überlegungen - außerhalb Webroot speichern - nicht zu. Wenn's gelingt, Schadcode reinzufummeln, kommt der dann trotzdem bei der Anzeige zur Ausführung.
        Du kannst bestimmte Aspekte prüfen, andere wiederum nicht.

        Eine gewisse Anzahl von Dateitypen kannst du mit getimagesize() verifizieren. Das sucht nicht nur nach "magischen Bytes" am Dateianfang, sondern auch nach ein paar Metadaten (abhängig vom Format) und verifiziert dabei die Dateistruktur.

        Die FileInfo-Funktionen suchen nur nach magischen Bytes. Sie kennen zwar mehr Dateiformate als getimagesize() aber können keine manipulierten Dateien erkennen. Du kannst also keine Schutzwirkung erwarten.

        Nur die Endung des Dateinamens zu checken, bringt gar nichts, auch wenn Windows-Betriebssysteme das bis heute so machen.

        Einfach einen eindeutigen Namen zu generieren, ist simpler als eine allumfassende Prüfung auf gültige Dateinamen zu bauen. Schließlich musst du das bei ungültigen Namen sowieso machen.

        Ob ein Dateiname "gültig" ist, hängt vom Dateisystem und vom darauf operierenden Betriebssystem ab.

        * Windows kennt bspw. eine größere Zahl von Dateinamen, die eine Sonderfunktion haben (wie CON, LPT, ...). Manche Namen werden automatisch umgewandelt (bspw. wenn ein "." am Ende steht). Und das alles, obwohl bspw. NTFS oder ExFAT als Dateisystem damit umgehen könn(t)en.

        * Unter Unixoiden sind die Beschränkungen nicht ganz so schlimm, aber trotzdem kannst du bei einem Shared Hoster nicht sicher sein, welchen BSD-Dialekt oder welches Filesystem dort eingesetzt wird.

        Letztendlich sagt dir erst ein erfolgreich ausgeführtes file_put_contents() (oder eine verwandte Funktion), ob der Dateiname anerkannt wurde. Ein automatisch generierter Name, der nur unkritische Zeichen wie [a-z0-9] enthält, dürfte der verlässlichere Weg sein.

        Bliebe noch der Aspekt der Prüfung, der sich (derzeit noch) nicht automatisieren lässt: Inhalte (von Bildern, Videos, Texten, ...), die du nicht verbreiten darfst (weil Gesetze das verbieten, du die Rechte daran nicht besitzt, ...) oder möchtest (weil sich deine potenzielle Kundschaft davon abgestoßen fühlt). Hier hilft nur das Abspeichern außerhalb des wwwroot und Freischaltung nach persönlicher Sichtung.

        Dann müsste ich den in jede Datei vor/beim Upload einfügen? In PDF, Excel, Word...?
        Für eine minimale HTTP-Response brauchst du zum Status-Header noch einen Content-Type-Header. Hier hilft dir die Ausgabe von getimagesize() weiter. Der Header Content-Disposition hilft dem Browser beim Download von Dateiformaten, die er nicht selbst anzeigen kann.

        Anschließend kannst du die Datei per readfile($path) einlesen und an den Browser weiterschieben.

        Bei sehr großen Dateien kann es vorkommen, dass der Endnutzer mit schlechter Verbindungqualität den Download abbricht und später wieder an der abgebrochenen Stelle fortsetzen möchte. Dafür gibts Range-Requests. Der Client sagt dem Server(-Script), welche Bytes er downloaden möchte. Wenn dein Script Range-Requests bearbeiten kann, ist es wichtig, dass dem Client auch immer mitzuteilen. Dafür zuständig sind die Header Content-Length (wenn der Client noch nicht nach Byte-Ranges gefragt hat) und Content-Range.

        Es gibt einen Artikel im SelfHTML-Wiki, der viele Aspekte von Datei-Up- und Downloads mit PHP abdeckt. Leider ist er noch unvollständig (bspw. bei der Dateinamen-Prüfung) und an manchen Stellen nicht ganz korrekt (bspw. in Bezug auf die Cache-Control-Header). Aber es schadet nicht, mal einen Blick reinzuwerfen.
        Wenn man die Wurst schräg anschneidet, hält sie länger, weil die Scheiben größer sind.

        Kommentar


        • #19
          @fireweasel

          danke für den ausführlichen Beitrag. Klingt so, also gäbe es keine absolute Sicherheit.

          Noch eine Idee (für Bilder):

          Ich habe mal den Quellcode eines Bildes manipuliert und zusätzlich etwas reingeschrieben (einfaches Javascript). Die normale Prüfung (exif_imagetype() und anderes) lässt das Bild durch.

          Wenn ich das beim Upload mit
          PHP-Code:
          imagecreatefromjpeg($filename)
          // und
          imagecopyresampled($thumb$source0000$newwidth$newheight$width$height); 
          behandele, also so tue, als würde ich die Größe ändern, erfolgt kein Upload bzw. bei einer Prüfung
          PHP-Code:
          if (!$source)... 
          erfolgt eine Fehlermeldung.

          Wäre das ein Weg, den Upload von manipulierten Bilddateien zu verhindern?

          Kommentar


          • #20
            Das wäre scheinbar ein Weg, die von Dir eingebaute Schad-Variante abzufangen, aber sicher nicht, um alles abzufangen.
            100% Sicherheit bekommst Du hier genausowenig, wie anderswo.

            Ob Du das nun aber so einsetzt, mußt Du für Dich selbst entscheiden.
            Competence-Center -> Enjoy the Informatrix
            PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

            Kommentar


            • #21
              @Arne

              "mühsam ernährt sich das Eichhörnchen" - Weil's 100%ige Sicherheit nicht gibt (sonst würde sich niemand ins US Pentagon einhacken können *ggg*), will ich halt soviel Stolper-Fallen einbauen wie möglich....

              Kommentar


              • #22
                Das ist ja auch ok, solange Du Dir an irgendeiner Stelle die Frage stellst, ob das den Aufwand wert ist
                Competence-Center -> Enjoy the Informatrix
                PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

                Kommentar


                • #23
                  So, es ist mit mittlerem Aufwand erledigt. Danke an alle, die mir wertvolle Tipps gegeben haben.

                  Kommentar

                  Lädt...
                  X