Carga segura de imágenes, o Omisión de verificación de tipo mime de PHP

1

Al asegurar la carga de imágenes, hay básicamente tres enfoques que conozco (por supuesto, idealmente, se usan los tres):

  1. comprobar la extensión del archivo
  2. almacenar archivos cargados en un directorio no ejecutable fuera de webroot
  3. verifique el contenido / tipo mime del archivo

Para el tercer punto, hay varias funciones de PHP que se sugieren, la mayoría de las cuales pueden ser omitido al codificar el código en fragmentos de IDAT . Aquí están los resultados que obtengo:

<?php $image = 'imageshell.png';

echo exif_imagetype($image);
// -> 3 (IMAGETYPE_PNG)

echo "<br>" . getimagesize($image)[2];
// -> 3 (IMAGETYPE_PNG)

echo "<br>" . mime_content_type($image);
// -> image/png

echo "<br>" . finfo_file(finfo_open(FILEINFO_MIME_TYPE), $image);
// -> image/png

echo "<br>" . finfo_file(finfo_open(FILEINFO_MIME_TYPE, "/usr/share/misc/magic"), $image);
// -> application/octet-stream

Básicamente tengo estas preguntas ahora:

  1. ¿Por qué el resultado es diferente si paso un archivo mágico (no debería seguir aceptando el archivo como un archivo de imagen, ya que eso es lo que realmente es?), qué es exactamente un archivo mágico, y qué hace PHP incorporado. aspecto de archivo mágico?
  2. ¿Puedo verificar de antemano si el sistema tiene un archivo mágico que resulte en la identificación correcta de una no-imagen o una imagen que contenga código PHP?
  3. Si no puedo, ¿hay un mejor enfoque para verificar si un archivo de imagen contiene código PHP?
  4. ¿También es posible omitir la última comprobación, la que resulta en application/octet-stream , también?
pregunta tim 21.02.2016 - 21:29
fuente

1 respuesta

2
  

¿Por qué el resultado es diferente si paso un archivo mágico (no debería seguir aceptando el archivo como un archivo de imagen, ya que eso es lo que realmente es?), qué es exactamente un archivo mágico, y qué hace PHP incorporado. aspecto de archivo mágico?

Un archivo mágico es la descripción de algunas heurísticas para determinar el tipo de archivo. Diferentes resultados pueden ser causados por diferentes archivos mágicos pero también diferentes implementaciones del motor heurístico.

  

¿Puedo verificar de antemano si el sistema tiene un archivo mágico que resulte en la identificación correcta de una imagen que no sea de imagen o que contenga código PHP?

Las diversas funciones de magia de archivos están diseñadas para detectar el tipo de archivo solo mirando unos pocos bytes al principio. No están diseñados para averiguar si hay un código PHP oculto dentro del archivo. Debería ser posible crear un documento políglota que sea a la vez PHP válido y una imagen válida.

Lo que significa que verificar el contenido / mimo no es una validación suficiente.

  

Si no puedo, ¿hay un mejor enfoque para verificar si un archivo de imagen contiene código PHP?

Es mejor no solo verificar, sino asegurarse. Esto se puede hacer convirtiendo la imagen en un formato diferente y eliminando toda la metainformación.

  

almacene los archivos cargados en un directorio no ejecutable fuera de webroot

Esa es realmente la mejor manera. Pero asegúrese también de que no pueda ser engañado para incluir el archivo en otro script PHP, es decir, Inclusión de archivos locales .

    
respondido por el Steffen Ullrich 21.02.2016 - 21:54
fuente

Lea otras preguntas en las etiquetas