2012-09-07 8 views
7

He creado (usando a script y algo de ayuda de Stack y algo de ayuda de amigos, sé muy poco acerca de PHP) una página simple para una publicación local sin fines de lucro donde las personas pueden cargar fotos.¿Cómo puedo proteger un script de carga de imágenes PHP de exploits?

no estoy muy bien con la seguridad (de una base de la ignorancia, no negligencia deliberada), pero me he tomado las siguientes medidas para proteger a esta página:

• el script PHP está configurado para aceptar solamente .jpg , archivos .png y .tif para cargar;
• la subcarpeta a la que guarda el contenido del formulario tiene permisos establecidos en 700, y la subcarpeta a la que guarda las fotos cargadas tiene permisos establecidos en 700;
• según la documentación, mi anfitrión tiene la siguiente configuración para asegurar que sólo los archivos .php ejecutan como .php:

<FilesMatch \.php$> 
    SetHandler php52-fcgi 
</FilesMatch> 

• He puesto un archivo .htaccess en el correspondiente (principal y se guarda el contenido) carpetas:

RemoveHandler .php 
RemoveHandler .inc 
RemoveHandler .pl 
RemoveHandler .cgi 
RemoveHandler .py 
RemoveHandler .fcgi 

noche a la mañana, sin embargo, alguien encontraron esta página de prueba y presentaron lo que parece ser un mensaje de prueba perfectamente benignas y pequeña .jpg. Esta es una página de prueba privada con una URL no intuitiva que solo yo y otras tres personas conocemos; ninguno de los otros envió esta prueba.

Esto, obviamente, me tiene preocupado de que esté ocurriendo algo raro, y me preocupa no saber lo suficiente sobre seguridad para asegurarme de que esta página es segura.

¿Hay algo obvio que me falta?

+0

el nombre de archivo proporcionado por el usuario (en '$ _FILES ['upload'] ['name']') no es confiable y se puede cambiar fácilmente. No verifique estas extensiones Compruebe el tipo de mime si comprueba si 'getimagesize()' devuelve un resultado válido. Si es posible, genera tu propio nombre de archivo. – MarcDefiant

Respuesta

8

Cuando se trata de cargar, debe tener en cuenta que todos los datos que puede encontrar en la matriz $ _FILES pueden ser falsificados. Está viajando a través de HTTP, por lo que es bastante fácil darle la imagen/jpg mime a un archivo ejecutable, por ejemplo.

1- Comprobar el verdadero mimo

PHP vienen con alguna función para comprobar el verdadero mimo de un archivo. Para que se debe utilizar fileinfo

$finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic"); 
$filename = "/var/tmp/afile.jpg"; 
echo $finfo->file($filename); 

2- Comprobar propiedades de la imagen

Evidentemente, usted quiera subir única imagen, por lo que el archivo recibido debe tener una anchura y una altura:

Uso getImageSize() para obtener toda la información requerida sobre la imagen. Si devuelve falso, el archivo probablemente no sea una imagen y usted puede eliminarlo. getImageSize también puede darle un tipo de mimo, pero no sé si puede confiar.

2.5- imagen Reprocess

Como sugiere user628405, el reprocesamiento de la imagen con GD es probablemente la cosa más segura a hacer.

$img = imagecreatefrompng('vulnerable.png'); 
imagepng($img, 'safe.png'); 

Obviamente tiene que ser adaptado de acuerdo con el tipo de imagen. Vea todos los imagecreatefrom * en la documentación de php.

3- Subir carpeta Además de lo que ya lo han hecho:

Asegúrese de que su carpeta de carga no está disponible en la web. Valide el archivo cargado, luego muévalo a otra carpeta si es necesario y cambie el nombre del archivo. Evitará que el hacker ejecute un archivo malicioso (no puede ejecutarlo si no puede ser alcanzado por una url).

Más información: https://www.owasp.org/index.php/Unrestricted_File_Upload

+2

Una vez tuve una situación cuando un tipo subió al archivo PNG de mi servidor web con '' Insertado en datos binarios. Este código no es ejecutable, pero aún se puede acceder a través de la función 'include()'. Y desafortunadamente 'getimagesize()' devolvió valor no falso. Logré esta situación con el re-guardado de todas las imágenes cargadas por '$ img = imagecreatefrompng ('vulnerable.png'); imagepng ($ img, 'safe.png'); ' – CodingHamster

+0

Soy bastante nuevo en todo esto, y no tengo miedo de hacer mi propia tarea, pero tengo un par de preguntas: primero, voy a agregar los comandos fileinfo y getImageSize , así como el bit de cambio de nombre de archivo, dentro de la porción "del archivo de caso" del script? – JeanSibelius

+0

Todo el control se debe hacer lo más pronto posible en la variable '$ _FILES ['my_files'] ['tmp_name']'; Si todo sale bien, puede mover el archivo, cambiarle el nombre y hacer lo que tenga que hacer con él. – grunk

0

Puede verificar el tipo MIME del archivo, pero no se preocupe, siempre y cuando su gestor de php solo pueda ejecutar archivos .php y se está ocupando de no guardar los archivos .php cargados en su script, ' no exponer ninguna fuga de seguridad.

Esto es válido para los archivos .php, así como para cualquier otro lenguaje de scripting del lado del servidor instalado en su servidor, por supuesto.

Una mejor idea es mantener un blanco de las extensiones que está aceptando guardar en su sistema de archivos.

+1

Esto no está directamente relacionado con la carga de campo, pero puede cargar una imagen con algún código PHP malicous como comentario. Si hay una vulnerabilidad LFI en el sitio, probablemente podría incluir su imagen y ejecutar el código malicioso. – MarcDefiant

0

Ignoraría el tipo MIME y la extensión de archivo del archivo entrante. Estos pueden ser falsificados.

Almacene esos archivos en un directorio si va por esa avenida.

Asegúrese de que ese directorio sea solo para imágenes (música) y luego obtenga una secuencia de comandos para ubicar la extensión correcta al mirar el formato de los archivos.

También asegúrese de que ese directorio no pueda ejecutar PHP (o cualquier otra cosa).

Esto lo mantendrá a salvo.

4

No confíe en ningún dato del cliente, incluyendo el tipo de contenido!

No guarde los archivos cargados en la raíz web. Los archivos cargados solo deben ser accesibles a través de sus scripts, para un mejor control.

¡No guarde los archivos cargados con sus nombres de archivo y extensiones originales! Almacene estos datos en una base de datos para recuperarlos más tarde.

Cuestiones relacionadas