- og hvis endelig filendelsen ikke stemmer overens med MIME typen, er der med højglansforkromet statsgaranti nogen, der laver pjat-røv med dig ... og så er der kun en vej for filen! ;o)
Synes godt om
Slettet bruger
30. juli 2009 - 13:26#6
Teoretisk set kan filen vel bare indeholde information om filtypen og intet andet, så jeg ved skam godt, at det er umuligt at validere den ud fra en typeopgivning alene. Uanset hvad har jeg altså behov for at håndtere eventuelle fejl ved imagecreatefromjpeg (og tilsvarende til øvrige filtyper), og det er fejlen her, der undrer mig. Med den tidligere opgivne kode prøvede jeg at uploade en korrumperet JPG-fil, hvilket resulterede i PHP-fejl - hvorfor? Skulle try/catch ikke fange dem?
- og får lige at være helt sikker: Hvis du tester på MIME typen, kan jeg lægge din server ned og slette alt på den. Det kan jeg ikke, hvis du tester på filendelsen
Synes godt om
Slettet bruger
30. juli 2009 - 14:46#9
/* Fancy kode der sørger for kun at lukke filer ind med den rigtige fil- og mimetype. */ if ($temporary = jpeg) { $preview = imagecreatefromjpeg($temporary); if ($preview) { //Filen var et jpeg billede. } else { //Filen var IKKE et jpeg billede, selvom den havde den rette endelse eller mime type. } }
#8, lægge serveren ned, hvordan? Uploade en eksekverbar fil, men med en image/jpeg mime type?
Synes godt om
Slettet bruger
30. juli 2009 - 14:56#10
#9#8 Ja, det vil jeg sgu også gerne vide...
#7 Det er meget muligt, at jeg ikke har forstået PHP's anvendelse af exceptions korrekt, da jeg ikke tidligere har anvendt dem. Jeg har antaget, at når PHP outputter fejlmeddelelser, er det et resultat af en unhandled exception - men dette er måske ikke korrekt? Eksempel:
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]: gd-jpeg, libjpeg: recoverable error: Premature end of JPEG file in /x/x.com/x.com/httpd.www/upload.php on line 27
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]: '/tmp/phpGRPKI7' is not a valid JPEG file in /x/x.com/x.com/httpd.www/upload.php on line 27
Ja, det er jo præcis problemet. Man kan sagtens uploade en fil med MIME type 'image/jpeg', som er eksekverbar. Netop derfor tester man ikke på MIME type, men på extension ;o)
Du kan altid undertrykke en fejl med et @: $noget = @funktion_som_ikke_eksisterer();
#11 Vedrørende sikkerhed: Hvorfor skulle filen eksekveres? Den gemmes jo som rå binær data.
Synes godt om
Slettet bruger
30. juli 2009 - 17:00#13
Ok, så følgende vil være hensigtsmæssigt til a) at teste, om formatet IFØLGE DEN INTERNE DATA ( :) ) er JPG b) evt. at rette filens extension c) lave en kopi i $preview ?
$type = $_FILES["file"]["type"]; if ($type == "image/jpeg" || $type == "image/pjpeg") { $preview = @imagecreatefromjpeg($temporary); if ($preview) { $separator = strpos($_FILES["file"]["type"], "."); if ($separator) $filename = substr($_FILES["file"]["type"], $separator + 1); else $filename = $_FILES["file"]["type"]."."; $filename .= "jpg"; } else $errors[] = "The format of the selected picture is not valid JPG."; }
Synes godt om
Slettet bruger
30. juli 2009 - 17:02#14
Rettelse: strpos skal selvfølgelig være strrpos :)
Synes godt om
Slettet bruger
30. juli 2009 - 18:43#15
Filen billede.php og mime typen "image/jpeg" gemmes i roden på serveren. Indholdet er følgende:
Så er det bare at kalde example.com/billede.php, og alle filer er væk.
Synes godt om
Slettet bruger
30. juli 2009 - 19:16#16
Ja, hvis a) filerne blev gemt som filer og ikke rå binær kode i en MySQL-database, b) jeg tillod filerne at beholde brugerspecificerede filnavne, så det bør vel ikke fungere med mit system?
Synes godt om
Slettet bruger
30. juli 2009 - 21:16#17
Det lader til at virke nu :)
// Analyze input if ($_FILES["file"]["size"] > 0) { $file = $_FILES["file"]["name"]; $temporary = $_FILES["file"]["tmp_name"]; $type = $_FILES["file"]["type"]; if ($type == "image/jpeg" || $type == "image/pjpeg") { $preview = @imagecreatefromjpeg($temporary); if ($preview) { $seperator = strrpos($file, "."); if ($seperator) $file = substr($file, $separator ); $file .= ".jpg"; } else $errors[] = "The format of the selected picture is not valid JPG."; } elseif ($type == "image/png" || $type == "image/x-png") { $preview = @imagecreatefrompng($temporary); if ($preview) { $seperator = strrpos($file, "."); if ($seperator) $file = substr($file, $separator ); $file .= ".png"; } else $errors[] = "The format of the selected picture is not valid PNG."; } elseif ($type == "image/jpeg" || $type == "image/gif") { $preview = @imagecreatefromgif($temporary); if ($preview) { $seperator = strrpos($file, "."); if ($seperator) $file = substr($file, $separator ); $file .= ".gif"; } else $errors[] = "The format of the selected picture is not valid GIF."; } else $errors[] = "The selected picture file is empty or does not exist."; }
Synes godt om
Slettet bruger
30. juli 2009 - 22:42#18
Nu fungerer skidtet. Jeg har imidlertid et mindre tillægsspørgsmål: Jeg anvender $preview til generering af et mindre billede som image-objekt. Hvordan kan jeg få dette objekt, endeligt kaldet $p, gemt i et blob-felt i databasen?
Tak, men faktisk vil jeg hellere gemme det som indholdet af en fil, så jeg ved visning kan arbejde med den binære data som indholdet af en billedfil. Hvordan kan jeg lettest få indholdet af f.eks. en JPG-fil ud fra image-objektet?
Til #12: "Vedrørende sikkerhed: Hvorfor skulle filen eksekveres? Den gemmes jo som rå binær data." >> Det bør du spørge 'ham', der uploader en eksekverbar fil og eksekverer den for at lægge din server ned og slette dine filer.
Til #16: "b) jeg tillod filerne at beholde brugerspecificerede filnavne, så det bør vel ikke fungere med mit system?" >> Ja, så kan du jo absolut ikke gøre det lettere for 'den onde' bruger =)
Synes godt om
Slettet bruger
31. juli 2009 - 12:53#24
Tak.
#23 Ups, b) er skrevet forkert :) Jeg mener, at alle filer genkendt som f.eks. JPG per MIME også får jpg-endelsen i stedet for deres oprindelige, altså at alle filer har extension jpg, png eller gif.
"Det bør du spørge 'ham', der uploader en eksekverbar fil og eksekverer den for at lægge din server ned og slette dine filer." Men hvordan skulle han eksekvere den? Den binære data bliver escaped og gemt i en blob, og når den udhentes, echo'er jeg den direkte til en fil med headers prædefinerede bestemmende filens type som f.eks. JPG - hvordan kan det nogensinde eksekveres?
1) Under upload gemmes al data som rå binær kode i en blob - ingen eksekvering 2) Under lagring kan "filen" ikke tilgås what se over - ingen eksekvering 3) Under download præsenteres files escapede indhold i f.eks. en JPG-fil med php-extension.
Sorry, jeg læste dit forrige indlæg, som om du gemte filen som en 'flad fil' =)
Jeg kan bare stadig ikke få det til at give mening at teste på noget, man ved, kan ændres. Jeg kan ikke se nogen somhelst begrundelse for at lave lige netop den test - men valget er jo dit =)
Synes godt om
Slettet bruger
31. juli 2009 - 14:05#26
#25 Tja, extension kan jo også ændres, og den angiver, teknisk set, kun hvilket program, der skal håndtere filen på den lokale maskine... Så principielt giver det vel ingen mening at diskriminere filer på baggrund af extensions? Anyway, ser sikkerheden fornuftig ud nu? Jeg vil nødig have besøg af en af de skumlere nørder på nettet...
Synes godt om
Slettet bruger
31. juli 2009 - 14:32#27
Ja, din sikkerhed ser fornuftig ud. Den tjekker efter mime-type og ændrer filnavnet, så det ikke er muligt at køre filer fra din server. Tilykke.
Synes godt om
Slettet bruger
31. juli 2009 - 14:45#28
Yay, I has a clever! Takker :)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.