Kolwitz: PHP Upload, aber nur Bilder.

Hallo, ich bin ein eifriger Mitleser, aber kein Mitschreiber. Doch nun starte ich einmal den Versuch!

Da ich einen Upload über PHP verwirklichen will.

In diesem Fall möchte ich nur JPG, JPEG, GIF, PNG erlauben und kein Bild grösser als 3 MB.

Weiter habe ich die Frage ist das OK über die MIME type, die Datei zu ermitteln? Ich speicher anschliessend die Bilder unter einem neuen Namen, mit der MIME Endung ab. Wie 252453245432.jpg

Als erstes habe ich das HTML Formular


<form action="#" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="userfile_pic" id="fileToUpload" accept="image/*">
    <input type="submit" value="Upload Image" name="submit">
</form>

anschließend behandle ich die übergebenen Daten so


if(isset($_GET['save'])) {

	$uploadgroesse =24000000;	 # 3 MB

	if( is_uploaded_file ( $_FILES['userfile_pic']['tmp_name'] ) )
		{
		if($_FILES['userfile_pic']['size'] < $uploadgroesse)
			{
				
			$finfo = new finfo(FILEINFO_MIME_TYPE);
			if (false === $ext = array_search(
				$finfo->file($_FILES['userfile_pic']['tmp_name']),
				array(
					'jpg' => 'image/jpg',
					'jpg' => 'image/jpeg',
					'png' => 'image/png',
					'gif' => 'image/gif',
				),true)) 
					{
					$error_msg = "Das ist keine JPG, JPEG, GIF oder PNG Datei";	
					}	
				else		
					{
					$success_msg = "Bild wird abgespeichert!.";  
          #
          # Hier speicher ich dann das Bild ab
          #
					}
			}
		else
			{
			$error_msg = "Das Bild ist zu Gross, max. 3 MB.";	
			}
		}
	else
		{
		$error_msg = "Es wurde Keine Bilddatei ausgewählt.";	
		}
}
  1. Tach!

    Weiter habe ich die Frage ist das OK über die MIME type, die Datei zu ermitteln?

    Ich nehme an, ja. Der schaut nicht nur auf die Dateiendung, sondern auf einen Teil des Inhalts. Vermutlich aber nur eine kurze Signatur. Man wird diesen Mechanismus sicher austricksen können. Solange es nur eine Absicherung gegen Fehlbedienung beim Dateiauswählen sein soll, ist das so ok.

    dedlfix.

    1. Hallo dedlfix,

      Man wird diesen Mechanismus sicher austricksen können. Solange es nur eine Absicherung gegen Fehlbedienung beim Dateiauswählen sein soll, ist das so ok.

      Denke ich auch, daher nur zur Ergänzung, mal einen Blick auf dieses Tutorial.

      Gruss
      Henry

  2. Lieber Kolwitz,

    In diesem Fall möchte ich nur JPG, JPEG, GIF, PNG erlauben und kein Bild grösser als 3 MB.

    OK. Ich würde diese Schritte gehen:

    1. Dateigröße prüfen und eventuell Upload verwefen
    2. die PHP-Funktion getimagesize() einsetzen: keine Abmessungen -> keine gültige Bilddatei
    3. Kopie mit neuem Namen und korrekter Dateiendung speichern

    Weiter habe ich die Frage ist das OK über die MIME type, die Datei zu ermitteln?

    Nein! Wenn der zweite Schritt (getimagesize()) erfolgreich Bildmaße ermittelt hat, dann kannst Du Dir sicher sein, dass Du auch wirklich eine gültige Bilddatei hast. Diese Prüfung ist nach bisherigem Wissensstand die sicherste. Danach interessiert Dich überhaupt erst der MIME-Typ.

    Siehe dazu auch hier im Wiki: Sicherheit bei File-Uploads

    Ich speicher anschliessend die Bilder unter einem neuen Namen, mit der MIME Endung ab. Wie 252453245432.jpg

    Also das, was ich im dritten Schritt formuliert habe. Prima!

    <form action="#" method="post" enctype="multipart/form-data">
        Select image to upload:
        <input type="file" name="userfile_pic" id="fileToUpload" accept="image/*">
        <input type="submit" value="Upload Image" name="submit">
    </form>
    

    Du möchtest "Select image to upload:" in ein <label> kleiden. Dazu hast Du zwei Möglichkeiten:

    <label>
      Select image to upload:
      <input type="file" name="userfile_pic" id="fileToUpload" accept="image/*">
    </label>
    
    <label for="fileToUpload">Select image to upload:</label>
    <input type="file" name="userfile_pic" id="fileToUpload" accept="image/*">
    

    Siehe auch hier im Wiki: Angaben für die Benutzerführung (Beschriftungen)

    Liebe Grüße,

    Felix Riesterer.

  3. Hello,

    es gab zu dem Thema schon mal einen ausführlichen Wiki-Beitrag, der bereits sehr viele Aspekte des Uploads beleuchtet hat:

    https://wiki.selfhtml.org/wiki/PHP/Tutorials/File_Upload

    Der Artikel ist garantiert nicht vollständig und wird es vermutlich auch nie sein können. Aber Du solltest ihn vollständig gelesen und verstanden haben.

    Bei qualifizierten Einwänden und/oder Rückfragen zu den dargelegten Gedanken stehe ich Dir zur Verfügung.

    Liebe Grüße
    Tom S.

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
    1. Lieber TS,

      es gab zu dem Thema schon mal einen ausführlichen Wiki-Beitrag, der bereits sehr viele Aspekte des Uploads beleuchtet hat:

      https://wiki.selfhtml.org/wiki/PHP/Tutorials/File_Upload

      den hatte ich doch auch schon verlinkt! Speziell ins Kapitel "Sicherheit" habe ich den Link gesetzt.

      Liebe Grüße,

      Felix Riesterer.

      1. Hello lieber Felix,

        es gab zu dem Thema schon mal einen ausführlichen Wiki-Beitrag, der bereits sehr viele Aspekte des Uploads beleuchtet hat:

        https://wiki.selfhtml.org/wiki/PHP/Tutorials/File_Upload

        den hatte ich doch auch schon verlinkt! Speziell ins Kapitel "Sicherheit" habe ich den Link gesetzt.

        Vielen Dank dafür.
        Aber wenn Du dir die Postingzeiten anschaust, dann hat sich das zeitlich einfach überschnitten. Man braucht doch immer ein paar Minuten, um das OP-Posting zu lesen und die Antworten darauf und dann passende Beiträge zum Verlinken wiedrzufinden.

        Es wäre garantiert an der Zeit, den Artikel nochmals zu ergänzen und zu überarbeiten. Speziell die diskreten Tipps zu AJAX und ASW (Active Web Sockets, es gelten zwar die grundlegenden Regeln, aber die werden oft ncht erkannt) fehlen da noch und dann ist die Passage für die generische Gefährdungserkennung (welcher Dateityp liegt vor?) noch immer eines meiner Anliegen.

        Leider ist meine verfügbare Hardware inzwischen so langsam, dass ich nicht mehr aus dem Knie komme. Ich brauch mal einen Lottogewinn :-O

        Liebe Grüße
        Tom S.

        --
        Es gibt nichts Gutes, außer man tut es!
        Das Leben selbst ist der Sinn.
  4. Hi,

    anschließend behandle ich die übergebenen Daten so

    	$uploadgroesse =24000000;	 # 3 MB
    

    Meine Vorstellung von 3MB unterscheidet sich deutlich von Deiner. Ich käme auf

     	$uploadgroesse = 3000000;	 # 3 MB
    

    oder auch (wenn man 1024 statt 1000 als Faktor nimmt)

     	$uploadgroesse = 3145728;	 # 3 MB
    

    cu,
    Andreas a/k/a MudGuard

    1. Hallo @MudGuard,

      	$uploadgroesse =24000000;	 # 3 MB
      

      Meine Vorstellung von 3MB unterscheidet sich deutlich von Deiner.

      24000000 / 3 = 8000000 – sind das etwa diese „Octet“ aus dem Französischen? 😉

      Viele Grüße
      Robert

  5. hi,

    accept="image/*" bewirkt lediglich, daß der aufpoppende Dialog zur Dateiauswahl eben nur Grafikdateien zeigt. Was jedoch die händische Eingabe beliebig anderer Dateien nicht verhindert.

    Etwas komfortabler wird es, wenn Du die FileAPI verwendest, komfortabler hinsichtlich einer Prüfung, siehe Attribute type was also befragt werden kann.

    MfG

    1. Hallo pl,

      accept="image/*" bewirkt lediglich, daß der aufpoppende Dialog zur Dateiauswahl eben nur Grafikdateien zeigt.

      Weil image/* – meinem Verständnis nach – alle Bildtypen meint (TIFFs und BMPs sind ja auch Bilder), wäre es vielleicht tatsächlich besser, die Mime-Types und Endungen anzugeben, wie es der HTML-Standard empfiehlt: image/jpeg,image/png,image/gif,.jpg,.jpeg,.png,.gif (für den Fall, dass GIF, JPEG und PNG erlaubt sein sollen)

      Was jedoch die händische Eingabe beliebig anderer Dateien nicht verhindert.

      Browsern wird im Standard empfohlen, nichts anderes zuzulassen. Gegen Client-seitige Manipulationen hilft sowieso nur eine Server-seitige Überprüfung.

      Gruß
      Julius

    2. hi,

      Etwas komfortabler wird es, wenn Du die FileAPI verwendest, komfortabler hinsichtlich einer Prüfung, siehe Attribute type was also befragt werden kann.

      Und: Es ergibt sich die Möglichkeit einer Vorschau! Auch das kann dazu beitragen, daß nur Bilder, also nicht versehentlich NichtBilder hochgeladen werden.

      Es ist ja nicht so, daß Benutzer nur böse Absichten haben. MfG