Come verificare i tipi di file caricati in PHP?

Sul sito web di PHP, l'unico vero controllo che suggeriscono sta usando is_uploaded_file() o move_uploaded_file() , qui . Ovviamente di solito non si desidera che l'utente carichi qualsiasi tipo di file, per una serie di motivi.

Per questo motivo, ho spesso usato alcuni controlli "mime" di tipo "rigoroso". Naturalmente questo è molto sbagliato perché spesso i tipi di mime sono sbagliati e gli utenti non possono caricare il loro file. È anche molto facile da falsificare e / o cambiare. E insieme a tutto questo, each browser e sistema operativo si occupa di loro in modo diverso.

Un altro metodo è controllare l'estensione, che ovviamente è ancora più semplice da modificare rispetto al tipo MIME.

Se vuoi solo immagini, usa qualcosa come getimagesize() functionrà.

E gli altri tipi di file? PDF, documenti Word o file Excel? O anche solo i file di text?

Modifica: se non hai mime_content_type o Fileinfo e system ("file -bi $ uploadedfile") ti dà il tipo di file sbagliato, quali altre opzioni ci sono?

Dai un'occhiata a mime_content_type o Fileinfo . Questi sono comandi PHP incorporati per determinare il tipo di un file osservando il contenuto del file. Controlla anche i commenti sulle due pagine precedenti, ci sono altri buoni suggerimenti.

Personalmente ho avuto la fortuna di usare qualcosa che è essenzialmente di system("file -bi $uploadedfile") , ma non sono sicuro che sia il metodo migliore.

IMHO, tutti i methods di controllo del tipo MIME sono inutili.

Supponiamo che tu abbia l' application/pdf tipo MIME. I methods standard stanno cercando di trovare qualcosa che assomigli a un'intestazione PDF ( %PDF- o smth. Come quella) e restituiranno 'Ok, sembra che questo sia un file PDF' in caso di successo. Ma in realtà questo non significa niente. Puoi caricare un file contenente solo %PDF-1.4 e passerà il controllo MIME.

Voglio dire se il file ha un tipo MIME atteso – passerà sempre il controllo di tipo MIME altrimenti il ​​risultato non è definito.

Presumo che avrai una list bianca fissa di tipi di file che accetteresti.

Per ognuno di questi tipi, dovrai utilizzare tecniche diverse per verificare che siano validi esempi di quel formato.

Ci sono due domande correlate:

  • Sembra approssimativamente come potrebbe essere il tipo giusto? (Per JPEG, puoi controllare le intestazioni, come hai detto. Per molti formati basati su Unix, puoi controllare il "magic cookie".)

  • È in realtà un esempio valido di quel tipo (ad esempio, per qualsiasi formato di tipo XML, è ansible validationre una DTD).

Penso che, per each formato, dovresti fare domande separate per ognuno, perché la risposta sarà abbastanza diversa per i PDF rispetto ai file ZIP.

Ho usato mime_content_type che è compatibile con PHP 5.2, perché non posso usare né Fileinfo (richiede PHP 5.3) né system() , che è disabilitato dal mio provider. Ad esempio, controllo se un file è un file di text, quindi:

 if (strcmp(substr(mime_content_type($f),0,4),"text")==0) { ... } 

Puoi vedere un esempio completo nella mia "Directory PHP e listener sottodirectory e visualizzatore di file e downloader" all'indirizzo: http://www.galgani.it/software_repository/index.php

Ecco la function file_mime_type di iZend:

 function file_mime_type($file, $encoding=true) { $mime=false; if (function_exists('finfo_file')) { $finfo = finfo_open(FILEINFO_MIME); $mime = finfo_file($finfo, $file); finfo_close($finfo); } else if (substr(PHP_OS, 0, 3) == 'WIN') { $mime = mime_content_type($file); } else { $file = escapeshellarg($file); $cmd = "file -iL $file"; exec($cmd, $output, $r); if ($r == 0) { $mime = substr($output[0], strpos($output[0], ': ')+2); } } if (!$mime) { return false; } if ($encoding) { return $mime; } return substr($mime, 0, strpos($mime, '; ')); } 
 if(isset($_FILES['uploaded'])) { $temp = explode(".", $_FILES["uploaded"]["name"]); $allowedExts = arrays("txt","htm","html","php","css","js","json","xml","swf","flv","pdf","psd","ai","eps","eps","ps","doc","rtf","ppt","odt","ods"); $extension = end($temp); if( in_arrays($extension, $allowedExts)) { //code.... } else { echo "Error,not Documentum type..."; } }