¿Cómo puedo evitar que cada archivo malicioso se cargue en mi servidor? (verifique el tipo de archivo)?

Mi problema es evitar que los usuarios carguen algún archivo malicioso en mi servidor web. Estoy trabajando en el entorno de Linux (debian).

En realidad, las cargas se manejan a través de php con este código:

function checkFile($nomeFile, $myExt = false){ if($myExt != false){ $goodExt = "_$myExt"."_"; }else{ $goodExt = "_.jpg_.bmp_.zip_.pdf_.gif_.doc_.xls_.csv_.docx_.rar_"; } $punto = strrpos($nomeFile, '.'); $ext = "_".substr($nomeFile, $punto, 8)."_"; if(stristr($goodExt, $ext)){ return 1; }else{ return 0; } } 

Aquí puedo especificar las extensiones que se pueden cargar, y si el archivo no las encuentro, las elimino tan pronto como se completa la carga. Pero de esta forma el usuario puede cambiar la extensión de archivo con un simple cambio de nombre … y eso es malo para mí; incluso si un file.exe (por ejemplo) nunca se ejecutará si se renombra en file.jpg (¿estoy en lo cierto?), no quiero tener posibles archivos de peligro en mi servidor.

Hay una forma, en php, python o whatelse, de que un sistema Unix funcione fácilmente, para verificar el verdadero tipo de archivo.

Probé el módulo mimetypes de python, pero recupero el tipo mime ipotético del archivo … basado en la extensión -.-

Necesitará validar que el archivo cargado es realmente del tipo que la extensión indica que es. Puede hacerlo a través de varios métodos, probablemente el más fácil sea a través del comando de file . No sé si tiene una API. Puedes probarlo tú mismo en el caparazón. Para su ejemplo de file.exe que se renombró a file.jpg antes de ser cargado, ejecute el file file.jpg e imprimirá algo que le dirá que es un ejecutable. Sin embargo, puede ser engañado.

Supongo que no sabe mucho sobre los permisos de archivos de Linux si cree que .exe significa que se ejecutará. En Linux, solo el bit de ejecución en los permisos del archivo determina eso: puede ejecutar cualquier archivo, independientemente de la extensión, si ese bit está activado. No lo configure en ningún archivo cargado y debe estar seguro de ejecutarlos. Es posible que todavía los esté devolviendo a los visitantes de su sitio, por lo que podría seguir siendo un vector para ataques XSS, así que tenga cuidado con eso.

Tengo miedo de decir que la respuesta que seleccionó como correcta no es correcta. Lo que hace el comando de archivo es leer un archivo en su sistema Linux, / usr / share / file / magic , que tiene firmas de archivos. Por ejemplo, una imagen GIF comienza con el texto GIF8 , o un archivo JPEG comienza con los bytes 0xffd8 . Solo necesita tener esas firmas en el archivo que carga para engañar al comando de archivo . Estos dos archivos se aceptarían como imágenes, aunque se ejecutarían como código php:

eval_gif.php:

 GIF8 

eval_jpg.php (hexdump):

 ff d8 3c 3f 70 68 70 20 65 76 61 6c 28 24 5f 47 |....| 

Estos son los errores más comunes al filtrar:

  • No filtro en absoluto.
  • Filtro basado en expresiones regulares incorrectas fácilmente anulables.
  • No usar las funciones is_uploaded_file y move_uploaded_file puede llegar a las vulnerabilidades de LFI.
  • No usar la matriz $ _FILES (usando variables globales en su lugar) puede llegar a las vulnerabilidades de RFI.
  • Filtro basado en el tipo de la matriz $ _FILES, fakeable como viene del navegador.
  • Filtro basado en el tipo de mime comprobado del lado del servidor, engañado simulando lo que contienen los archivos mágicos (es decir, un archivo con este contenido GIF8 se identifica como un archivo de imagen / gif pero se ejecuta perfectamente como un script php)
  • Utilice la lista negra de archivos o extensiones peligrosos en lugar de incluir en la lista blanca aquellos que están explícitamente permitidos.
  • Configuraciones de apache incorrectas que permiten cargar archivos .htaccess que redefinen las extensiones ejecutables de php (es decir, txt).

Los usuarios no deberían poder ejecutar los archivos que cargan. Quite su permiso para ejecutar.

Hay una forma, en php, python o whatelse, de que un sistema Unix funcione fácilmente, para verificar el verdadero tipo de archivo.

No.

Puede crear un archivo llamado, por ejemplo, “algo.pdf”, que es un documento PDF perfectamente válido pero que todavía contiene cadenas de firmas como ““. Cuando se encuentra con Internet Explorer (y hasta cierto punto con otros navegadores, pero IE es peor), este documento puede tomarse como HTML en lugar de PDF, incluso si lo sirvió con el tipo de medio MIME correcto. Luego, dado que HTML puede contener JavaScript controlando la interacción del usuario con su sitio, su aplicación sufre un agujero de seguridad de scripts entre sitios.

Content-sniffing es un desastre de seguridad. Consulte esta publicación para conocer algunas soluciones generales: detener a las personas que cargan archivos PHP maliciosos a través de formularios.

Normalmente, utiliza el comando ‘archivo’ para descubrir qué contiene un archivo. No estoy seguro, sin embargo, si detectará archivos .exe:

http://unixhelp.ed.ac.uk/CGI/man-cgi?file

tu, solía decir ‘ejecutado’ por ejemplo-significado. Verdaderamente, tuve un problema hace dos años: un sombrero blanco justo subió un archivo php a mi servidor, lo ejecutó, y el archivo autocreó un tipo de CMS para controlar mi servidor con el permiso de usuario php … luego simplemente me envió un correo electrónico que decía, menos o más: ‘Su aplicación no es segura. Para la demostración, no he hecho esto y eso … ‘

De hecho, después de verificar cada permiso en cada archivo que tengo en mi servidor, pero aún así no me gusta la idea de tener algún archivo malicius en él.

Voy a probar la función de archivo Unix, ya he visto que puedo recuperar el resultado por un código como ese:

  

Con algo de afinación espero que sea seguro.

@Paolo Bergantino: mi aplicación es un servicio basado en la web, las personas cargan imágenes, documentos pdf, archivos csv, ecc …, pero la descarga no es la única acción que pueden realizar; Las imágenes, por ejemplo, se deben mostrar en la página pública del usuario. La forma en que creo que voy a tomar es que:

  1. Sube el archivo;
  2. Verifique el tipo de archivo con el archivo passthru;
  3. Eliminar si no está claro;
  4. De lo contrario, muévelo al directorio del usuario (nombrado con cadenas de randoms)

Gracias a todos.