2008-11-22 18 views
46

En el sitio web de PHP, la única comprobación real que sugieren es usar is_uploaded_file() o move_uploaded_file(), here. Por supuesto, generalmente no desea que el usuario cargue ningún tipo de archivo por una variedad de razones.¿Cómo verificar los tipos de archivos cargados en PHP?

Debido a esto, a menudo he utilizado alguna comprobación de tipo MIME "estricta". Por supuesto, esto es muy defectuoso porque a menudo los tipos de mime son incorrectos y los usuarios no pueden subir su archivo. También es muy fácil de falsificar y/o cambiar. Y junto con todo eso, cada navegador y sistema operativo los trata de manera diferente.

Otro método es verificar la extensión, que por supuesto es incluso más fácil de cambiar que el tipo de mimo.

Si solo quiere imágenes, usar algo como getimagesize() funcionará.

¿Qué pasa con otros tipos de archivos? PDF, documentos de Word o archivos de Excel? ¿O incluso solo archivos de texto?

Editar: Si usted no tiene mime_content_type o Fileinfo y el sistema ("presentar -bi $ UploadedFile") le da el tipo de archivo incorrecto, ¿qué otras opciones hay?

+0

el 'getimagesize()' función establece claramente que se no debería usar esta función para validar si una imagen es una imagen. 'No use getimagesize() para verificar que un archivo determinado sea una imagen válida. Utilice una solución especialmente diseñada, como la extensión Fileinfo en su lugar. Http://php.net/manual/en/function.getimagesize.php –

Respuesta

31

Eche un vistazo a mime_content_type o Fileinfo. Estos son comandos integrados de PHP para determinar el tipo de archivo mirando el contenido del archivo. También verifique los comentarios en las dos páginas anteriores, hay algunas otras buenas sugerencias.

Personalmente he tenido mucha suerte con algo que es esencialmente system("file -bi $uploadedfile"), pero no estoy seguro de si ese es el mejor método.

+17

sistema ("archivo -bi -" .escapeshellarg ($ uploadedfile)) es más seguro. – Kornel

+0

Sí, escapo un poco, siempre tengo que tener cuidado con los ataques de inyección en PHP, pero era demasiado flojo para volver y comprobar realmente cuál era el comando que usaba. – davr

+1

He votado negativamente porque en realidad no proporcionó un fragmento de código de demostración y un código de referencia que no tenía fragmentos de demostración en su propia página de documentación. Por favor, actualice su respuesta y responda, y si funciona, con mucho gusto votaremos. – John

2

Supongo que va a tener una lista blanca fija de tipos de archivos que aceptará.

Para cada uno de estos tipos, tendrá que usar diferentes técnicas para verificar que sean ejemplos válidos de ese formato.

Hay dos preguntas relacionadas:

  • ¿Se ve más o menos como que podría ser el tipo correcto? (Para JPEG, podría verificar los encabezados, como mencionó. Para muchos formatos basados ​​en Unix, puede verificar la "cookie mágica").

  • Es en realidad un ejemplo válido de ese tipo (por ejemplo, para cualquier XML) formato -como, se podría validar contra un DTD.)

Creo que, para cada formato, usted debe hacer preguntas separadas para cada uno, porque la respuesta será muy diferente para los archivos PDF en comparación con archivos ZIP.

+1

Como se indica en la pregunta, getimagesize() funcionará perfectamente para las imágenes. –

+0

@Darryl Hein, ese es un punto justo. Editado – Oddthinking

13

En mi humilde opinión, todos los métodos de comprobación de tipo MIME son inútiles.

Supongamos que tiene que debe tener MIME-tipo application/pdf. Los métodos estándar están tratando de encontrar algo que se parece a un encabezado de PDF (%PDF- o algo así) y devolverán 'Bien, parece que este es un archivo PDF' si tiene éxito. Pero, de hecho, esto no significa nada. Puede cargar un archivo que contenga solo %PDF-1.4 y pasará la verificación MIME.

Es decir, si el archivo tiene un tipo MIME esperado, siempre pasará la verificación de tipo MIME; de lo contrario, el resultado no está definido.

+0

Cualquiera que piense que esta respuesta no es correcta, [lea esto] (http://stackoverflow.com/questions/8444638/how-to-read-header-of-a-file-uploaded-in-php#comment-10454480) Una revelación. –

+0

mime check no es completamente inútil. sigue siendo útil en la condición en que el usuario cargó el archivo no dañado. – KeepMove

2

Utilicé mime_content_type que es compatible con PHP 5.2, porque no puedo usar ni Fileinfo (requiere PHP 5.3) ni system(), que está deshabilitado por mi proveedor. Por ejemplo, puedo comprobar si un archivo es un archivo de texto para:

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

se puede ver un ejemplo completo en mi "Directorio de PHP y subdirectorio Listener & Visor de Archivos y Downloader" en: http://www.galgani.it/software_repository/index.php

1

aquí está la función de file_mime_type 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, '; ')); 
} 
1
if(isset($_FILES['uploaded'])) { 
    $temp = explode(".", $_FILES["uploaded"]["name"]); 

    $allowedExts = array("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_array($extension, $allowedExts)) { 
     //code.... 

    } else { 
     echo "Error,not Documentum type..."; 
    } 
} 
+1

¡No debe validar el tipo de archivo con la extensión! Esto no es seguro en absoluto y debe obtener mimo/tipo de archivo tmp. Además, usar el tipo de mime enviado por el cliente no es seguro. – Northys

+0

Si codifiqué un virus, y renombre como jpg. Estas muerto. – Hien

Cuestiones relacionadas