2012-04-08 17 views
6

estoy trabajando en un formulario de carga en php que debe permitir solo archivos mp3.es la detección de tipo MIME la mejor manera de detectar un tipo de archivo?

cuando se realiza la carga analizo el archivo para comprobar si realmente es un mp3 ... el primer paso es detectar el tipo mime como "audio/mpeg", utilizo las bibliotecas finfo_file() y funciona bien excepto que durante las pruebas de algunos mp3 son rechazadas porque sus resultados tipo mime como: application/octet-stream

mis preguntas son: - ¿debería mi aplicación rechazar definitivamente esos mp3? en realidad reproducen audio - ¿hay alguna razón por la cual este tipo de mimo es un mp3? - ¿es la detección del tipo de mimo la forma más segura de conocer el tipo de archivo?

Respuesta

0

Si desea una forma extremadamente robusta de detectar tipos de archivos sin simplemente confiar en que el cliente proporcione el tipo MIME correcto, use la utilidad file en UNIX.

$ file Black\ Sands\ 01\ Prelude.mp3 
Black Sands 01 Prelude.mp3: Audio file with ID3 version 2.2.0, contains: MPEG ADTS, layer III, v1, 320 kbps, 44.1 kHz, Stereo 

$ file homework/math475-hw8.docx 
homework/math475-hw8.docx: Microsoft Word 2007+ 

En PHP se puede utilizar la función exec para invocarlo.

+0

esta es una opción que no pensé ... y no puedo probar porque estoy ganando – enkore

+0

Hay una versión compilada para win32 [aquí] (http://gnuwin32.sourceforge.net/packages/ file.htm). –

+0

El comando 'file' y la función' finfo_file' de PHP usan los mismos métodos para determinar el tipo de mime (generalmente haciendo referencia a '/ usr/share/misc/magic'). No sirve de nada para 'exec file' cuando tienes una función incorporada. Sin embargo, tengo un caso aquí donde un '.mp3' se detecta como' application/octet-stream' tanto por 'finfo_file' como' file -I', cuando esperaría que devolviera 'audio/mpeg'. Ambos están fallando. Sin embargo, creo que esto se puede resolver pasando el camino a un archivo 'magic' mejorado como el segundo argumento para' finfo_open'. –

0

El mejor método de detección de archivos es utilizar el esquema "byte mágico" o "número mágico", además de MIME. Unix file (así como finfo_file) realmente usa "magic bytes" para hacer esta detección de archivos. Entonces, en resumen: sí.

No se preocupe tanto por cómo se ve su archivo, y más acerca de lo que puede hacer con él. Mientras juega, el archivo debería estar bien.

Si realmente quiere hacer más, puede buscar los bytes mágicos usted mismo. Hay a list of them here.

+0

es por eso que con la clase getid3() obtengo "audio/mpeg" pero con finfo_filei obtengo "application/octet-stream" en el mismo archivo ... esto es un poco raro ... pero incluso si el archivo es jugable, si los resultados con un tipo de mime diferente será rechazado por razones de seguridad (a menos que encuentre una mejor manera) .. me pregunto cuántos mp3s no tienen un mimo correcto ... – enkore

+1

@enkore "me pregunto cuántos mp3s no tienen un mimo correcto "El tipo MIME es suministrado por el cliente. No es inherente al archivo mp3 en sí. –

2

En la mayoría de mis aplicaciones donde es necesario cargar, a veces me conformo con validar el MIME que pasa el navegador (cliente) contra una lista de tipos MIME predefinidos. Este enfoque hace una suposición general de que si algo sospechoso sucede cuando el navegador no puede comunicar el tipo MIME de un archivo que se está cargando, probablemente no quiera molestarme en procesarlo en este momento.

<?php 

$valid_mp3_mimes = array(
    'audio/mpeg', 
    'audio/x-mpeg', 
    'audio/mp3', 
    'audio/x-mp3', 
    'audio/mpeg3', 
    'audio/x-mpeg3', 
    'audio/x-mpeg-3', 
    'audio/mpg', 
    'audio/x-mpg', 
    'audio/x-mpegaudio', 
    'video/mpeg', 
    'video/x-mpeg', 
); 

$uploaded_file_mime = $_FILES['upload_field_name']['type']; 

if(!in_array($uploaded_file_mime, $valid_mp3_mimes)) 
{ 
    die('Upload is not a valid MP3 file.'); 
} 

Puede que sienta o no que este es un método suficiente para sus propósitos. El Manual de PHP establece explícitamente que esta información está disponible si el navegador proporcionó esta información y que el tipo MIME NO se verifica por el lado del servidor y, por lo tanto, no debe darse por sentado.

Una cosa a tener en cuenta es la disponibilidad de recursos en el servidor que le permiten autenticar el verdadero tipo MIME de un archivo.

Como desarrolladores de PHP, nos encanta la flexibilidad de crear un código independiente de plataforma (por ejemplo, nuestras aplicaciones web creadas con un sistema Windows que ejecuta XAMPP pueden implementarse en un entorno de alojamiento Linux con muy pocas modificaciones). Sin embargo, al validar los tipos de MIME, comenzamos a introducir métodos dependientes de la plataforma que requieren verificar la existencia de estas herramientas (como "archivo" o "archivo_de_finfo").

Ésta podría ser una aplicación digna de estudio (tomada desde el repositorio GitHub CodeIgniter) que utiliza estas herramientas y se trata tan completa de un ejemplo de trabajo a medida que va a conseguir en el ámbito de PHP:

El tipo MIME de archivo detecta el tipo MIME (real) del archivo cargado, si es posible. https://github.com/EllisLab/CodeIgniter/blob/develop/system/libraries/Upload.php#L983


Fuentes

PHP Manual POST de archivos con el método - http://www.php.net/manual/en/features.file-upload.post-method.php

Webmaster Toolkit tipos MIME - http://www.webmaster-toolkit.com/mime-types.shtml

FILExt .MP3 Archivo - http://filext.com/file-extension/MP3

Cuestiones relacionadas