2008-10-08 5 views
12

Estoy programando algo que permite a los usuarios almacenar documentos e imágenes en un servidor web, para almacenarlos y recuperarlos más tarde. Cuando los usuarios cargan archivos en mi servidor, PHP me dice qué tipo de archivo está basado en la extensión. Sin embargo, me temo que los usuarios podrían renombrar un archivo zip como somezipfile.png y almacenarlo, manteniendo así un archivo zip en mi servidor. ¿Hay alguna forma razonable de abrir un archivo cargado y "verificar" para ver si realmente es del dicho tipo de archivo?¿Cómo puedo saber si alguien está falsificando un tipo de archivo? (PHP)

Respuesta

18

Magic number. Si puede leer los primeros bytes de un archivo binario, puede saber qué tipo de archivo es.

+0

números mágicos no son siempre a el principio. TGA, por ejemplo, los tiene al final, creo. –

+0

tenga en cuenta que al confiar en este control, los usuarios malintencionados pueden insertar bytes mágicos y luego escribir código PHP en el mismo archivo para intentar ejecutar algún código en su máquina – Jorre

+1

¿Hay algún ejemplo de cómo hacerlo? – CMCDragonkai

4

Tipo de. La mayoría de los tipos de archivos tienen algunos bytes reservados para marcarlos para que no tenga que depender de la extensión. El sitio http://wotsit.org es un gran recurso para encontrar esto para un tipo particular.

Si está en un sistema Unix, creo que el comando de archivo no depende de la extensión, por lo que puede pagarlo si no desea escribir el código de comprobación de bytes.

Para PNG (http://www.w3.org/TR/PNG-Rationale.html)

Los primeros ocho bytes de un archivo PNG siempre contener los siguientes valores:

(decimal) 137 80 78 71 13 10 26 10

(hexadecimal) 89 50 4E 47 0d 0a 1a 0a

(ASCII C notación) \ 211 PNG \ r \ n \ 032 \ n

2

Muchos tipos de archivos tienen "magic numbers" al principio del archivo para identificarlos. Puede leer algunos bytes del frente del archivo y compararlos con una lista de números mágicos conocidos.

1

En un sistema Unix, la captura de la salida del comando 'archivo' debe proporcionar información adecuada.

8

Compruebe la extensión PECL FileInfo para PHP, que puede hacer las búsquedas de magia MIME para usted.

2

Si sólo se trata de imágenes, a continuación, getimagesize() debe distinguir una imagen válida de uno falso.

$ php -r 'var_dump(getimagesize("b&n.jpg"));' 
array(7) { 
    [0]=> 
    int(200) 
    [1]=> 
    int(200) 
    [2]=> 
    int(2) 
    [3]=> 
    string(24) "width="200" height="200"" 
    ["bits"]=> 
    int(8) 
    ["channels"]=> 
    int(3) 
    ["mime"]=> 
    string(10) "image/jpeg" 
} 

$ php -r 'var_dump(getimagesize("/etc/passwd"));' 
bool(false) 

Un valor falso de getimagesize no es una imagen.

1

Como nota al margen me encontré con un problema similar en el que tuve que hacer mi propia verificación de tipos. La interfaz frontal de mi aplicación se realizó en flash. Los archivos se pasaban a través de flash a un script php. Cuando intentaba hacer una comprobación de tipo MIME utilizando php, el tipo siempre devuelto era application/octetstream porque venía de flash.

Tuve que implementar un paradigma tipo números mágicos. Simplemente creé un archivo xml que contenía el tipo de archivo junto con algunos patrones de definición que se encuentran al principio del archivo. Una vez que el archivo llegó al servidor hice una coincidencia de patrones con el archivo xml y luego acepté o rechacé el archivo. No noté ninguna disminución en el rendimiento real, ya sea que estaba esperando.

Esto es solo una nota al margen para cualquiera que pueda estar usando el flash como interfaz y tratando de verificar el archivo una vez que se haya cargado.

+0

¿Qué método usaste para comparar los archivos a tu referencia? –

+0

En el archivo xml tuve un attrib de la posición donde se puede encontrar la cadena mágica en el archivo. Así que leí en el número especificado de bytes del archivo y lo convertí en hexadecimal e hice una comparación. – JustLogic

1

Además de identificar el tipo de archivo, es posible que desee tener cuidado con los archivos que tengan otros archivos incrustados o anexados. Desafortunadamente, esto requerirá un análisis más profundo del contenido del archivo que simplemente usar "números mágicos".

Por ejemplo, http://quantumrook.wordpress.com/2007/06/06/hide-a-rar-file-in-a-jpg-file/ (este tipo particular de ocultación de datos puede ser fácilmente trabajado en todo por la carga y volver a guardar en un archivo nuevo los datos reales de la imagen .. otras serán más difíciles.)

Cuestiones relacionadas