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
Magic number. Si puede leer los primeros bytes de un archivo binario, puede saber qué tipo de archivo es.
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
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.
En un sistema Unix, la captura de la salida del comando 'archivo' debe proporcionar información adecuada.
Compruebe la extensión PECL FileInfo para PHP, que puede hacer las búsquedas de magia MIME para usted.
Para una respuesta exacta de cómo se puede hacer rápidamente esta en PHP, echa un vistazo a esta pregunta: How do I find the mime-type of a file with php?
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.
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.
¿Qué método usaste para comparar los archivos a tu referencia? –
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
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.)
- 1. ¿Cómo puedo saber si hay una página de php si alguien llegó por POST o GET?
- 2. ¿Cómo puedo saber si un secuenciador está cerrado?
- 3. ¿Cómo puedo saber si un archivo está en un sistema de archivos remoto con Perl?
- 4. ¿Cómo saber si un archivo está comprimido gzip?
- 5. PHP - ¿Cómo saber si X-Sendfile está disponible e instalado?
- 6. ¿Cómo puedo saber si un cliente web está bloqueando anuncios?
- 7. ¿Cómo puedo saber si un proceso se está ejecutando?
- 8. Dentro de un archivo por lotes, ¿cómo puedo saber si se está ejecutando un proceso?
- 9. ¿Cómo puedo saber si una impresora imprimirá en un archivo?
- 10. ¿Cómo saber si el socket está abierto en PHP?
- 11. Cómo saber si un actor está inactivo
- 12. ¿Cómo puedo saber si un archivo está abierto en otra parte de C en Linux?
- 13. ¿Cómo puedo determinar si un archivo está bloqueado con VBS?
- 14. ¿Cómo puedo saber si un archivo ya está creado en una StorageFolder?
- 15. ¿Cómo puedo saber el tipo de archivo usando Boost.Filesystem?
- 16. ¿Cómo puedo saber si el CouchDB está funcionando?
- 17. ¿Cómo puedo saber si Moodle cron está funcionando?
- 18. ¿Cómo puedo saber si Matlab está ocupado cuando usa GUI?
- 19. ¿Cómo puedo saber si .NET 3.5 SP1 está instalado?
- 20. ¿Cómo puedo saber si NSTimer está activo o no?
- 21. ¿Cómo puedo saber si la pantalla está activada en Android?
- 22. ¿Cómo saber si un archivo es extraído por alguien más en TFS 2010?
- 23. ¿Cómo puedo saber si se está mostrando ModalViewController?
- 24. ¿Cómo puedo saber si está instalado .NET 4.02?
- 25. ¿Cómo saber si un archivo es un enlace?
- 26. ¿Cómo puedo saber si la cámara está en uso?
- 27. ¿Cómo puedo saber si mi aplicación PHP usa demasiada memoria?
- 28. ¿Cómo saber si un manejador de archivo es un socket?
- 29. Cómo saber si el dispositivo está durmiendo
- 30. cómo saber si el correo php falló
números mágicos no son siempre a el principio. TGA, por ejemplo, los tiene al final, creo. –
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
¿Hay algún ejemplo de cómo hacerlo? – CMCDragonkai