2013-03-24 11 views
7

Jestem początkującym PHP i obecnie uczę się części "Sprawdzanie poprawności pliku".PHP Sprawdzanie poprawności przesłania pliku

zrobiłem stronę test.php zawierający następujący kod:

var_dump(@$_FILES['file']['type']); 

pierwsze, upload obrazu "img.gif" i wrócił:

string 'image/gif' (length=9) 

Potem zmienił obraz na rozszerzenie ".jpg" i powrócił:

string 'image/jpeg' (length=10) 

Więc sobie sprawę $ _FILES [ "plik"] [ "typ"] tylko powrócić przesłanego pliku rozszerzenie, ale w rzeczywistości nie sprawdzi, który to plik.

Na tej stronie http://www.w3schools.com/php/php_file_upload.asp znajduje się kod:

$allowedExts = array("gif", "jpeg", "jpg", "png"); 
$extension = end(explode(".", $_FILES["file"]["name"])); 
if ((($_FILES["file"]["type"] == "image/gif") 
|| ($_FILES["file"]["type"] == "image/jpeg") 
|| ($_FILES["file"]["type"] == "image/jpg") 
|| ($_FILES["file"]["type"] == "image/png")) 
&& ($_FILES["file"]["size"] < 20000) 
&& in_array($extension, $allowedExts)) 

dlaczego Powyższe kody dwukrotnie sprawdzić rozszerzenie pliku zastanawiam? Usunąłem niektóre z powyższych kodów i jest to mój nowy kod:

$allowedExts = array("gif", "jpeg", "jpg", "png"); 
$extension = end(explode(".", $_FILES["file"]["name"])); 
if (($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts)) 

Czy mój kod jest prawidłowy? A może masz lepszy sposób na sprawdzenie, czy plik do przesłania jest obrazem?

Dzięki!

+1

Dlaczego mój post został odrzucony? Chcę tylko upewnić się, że $ _FILES ["plik"] ["typ"] nie jest konieczny w kodach w3schools – nut

Odpowiedz

12

Powinieneś przekazać nazwę pliku tmp * do getimagesize, poda rozmiar i typ obrazu (jeśli jest to obraz). Jeśli przekazany argument jest plikiem, ale nie obrazem, zwraca wartość false, co pozwala na sprawdzenie poprawności.

Edycja: Jedyna wiarygodna metoda sprawdzania poprawności obrazu polega na zrobieniu kopii za pomocą GD lub Imagick - getimagesize can be easily hacked.

*: Mam na myśli tymczasowy plik utworzony po przesłaniu.

Na przykład:

if ($_SERVER['REQUEST_METHOD'] === 'POST') 
{ 
    $file = $_FILES['file']['tmp_name']; 
    if (file_exists($file)) 
    { 
     $imagesizedata = getimagesize($file); 
     if ($imagesizedata === FALSE) 
     { 
      //not image 
     } 
     else 
     { 
      //image 
      //use $imagesizedata to get extra info 
     } 
    } 
    else 
    { 
     //not file 
    } 
} 

Ten kod wykorzystuje file_exists prostu być ogólnie. Jeśli nie przesłano żadnego pliku, otrzymasz $_FILES['file']['size'] = 0, $_FILES['file']['tmp_name'] = '' i $_FILES['file']['error'] = 4. Zobacz także is_readable. Aby uzyskać informacje o błędach, zobacz file upload errors explained pod adresem php.net.

+0

dziękuję za wzmiankę o funkcji getimagesize – nut

+2

Zwróć uwagę, że sprawdza, czy jest to obraz, ale to nie znaczy, że nie jest obrazem, który został hartowany, zobacz: http://php.webtutor.pl/en/ 2011/05/13/php-code-injection-a-simple-virus-in-php-in-a-jpeg-image/Polecam odtworzenie obrazu za pomocą funkcji takich jak imagecreatefromstring i konwertowanie go na na przykład png. - Arie 50 minut temu – Arie

1
$allowedExts = array("gif", "jpeg", "jpg", "png"); 
$extension = end(explode(".", $_FILES["file"]["name"])); 
if ((($_FILES["file"]["type"] == "image/gif") 
|| ($_FILES["file"]["type"] == "image/jpeg") 
|| ($_FILES["file"]["type"] == "image/jpg") 
|| ($_FILES["file"]["type"] == "image/png")) 
&& ($_FILES["file"]["size"] < 20000) 
&& in_array($extension, $allowedExts)) 

ta jest sprawdzana dwa razy, ponieważ rozszerzenie pliku i „typ pliku” mogą być różne, więc ktoś nie może przesłać plik wykonywalny z rozszerzeniem .png.

W zmodyfikowanym kodzie możliwe jest przesłanie pliku innego typu ze zmodyfikowanym rozszerzeniem. np. mogą przesłać dokument tekstowy z rozszerzeniem ".png".

Twój nowy kod jest tylko sprawdzeniem rozszerzenia i nie ma podwójnego sprawdzenia.

+3

Przesłałem plik exe z rozszerzeniem png, zwróconą stroną: ciąg "image/png" (długość = 9) – nut

0

Twój nowy kod sprawdza tylko rozszerzenie pliku i rozmiar pliku. Nie sprawdza typu pliku.

Zdecydowanie zalecam używanie starego kodu, ponieważ sprawdza on również typ pliku.

+1

var_dump (@ $ _ PLIK ['plik'] ['typ']) zwrócił ciąg 'image/png' (length = 9) dla pliku exe, ale z rozszerzeniem png, więc nie sprawdził typu pliku, ale tylko rozbudowa. – nut

Powiązane problemy