¿Es seguro servir cualquier archivo subido por el usuario solo con los tipos de contenido MIME incluidos en la lista blanca?

16

Digamos que desarrollo una aplicación que,

  1. Permite a cualquier usuario cargar un archivo de solo tipo de contenido y extensiones de mimo en lista blanca (word y pdf).
  2. Sirve esos archivos con la extensión permitida y el tipo de contenido.

¿Esto es un riesgo de seguridad? ¿Por qué?

¿Algún explorador inferirá el tipo de contenido de los bytes del archivo (usando encabezados mágicos) y descartará el tipo de contenido que estoy especificando en los encabezados?

¿Cuál es la solución para hacer esto seguro? ¿Debo afirmar que los archivos que se cargan tienen bytes mágicos que coincidan con el tipo mime proporcionado por el cliente?

Sé que esta pregunta es similar a ¿Es seguro almacenar y reproducir los tipos mime proporcionados por el usuario? , pero no creas que es un duplicado.

    
pregunta Andy 15.02.2012 - 18:17
fuente

4 respuestas

11
  1. Detección de contenido HTML, tal como lo describe Krzysztof; principalmente, pero no exclusivamente, IE.

  2. jar: vulnerabilidad de URL en Firefox anterior

  3. Contenido similar a un archivo JAR ( GIFAR et al): aloja algo que podría interpretarse como un Java archive implica XSS debido a las diferentes Políticas de Mismo Origen aplicadas por Java.

  4. Un archivo que contiene algo que se parece un poco al contenido de crossdomain.xml puede ser dirigido por la llamada a loadPolicyFile para obtener XSS para un llamador Flash.

  

¿Debo afirmar que los archivos que se están cargando tienen bytes mágicos que coinciden con el tipo mime proporcionado por el cliente?

Insuficiente contra los camaleones (archivos igualmente válidos como para cualquier tipo).

  

¿Cuál es la solución para hacer esto seguro?

La única mitigación fuerte es servir tu contenido cargado que no es de confianza desde un nombre de host diferente de tu sitio principal.

  1. Ese nombre de host diferente puede ser un subdominio de su sitio principal si solo le preocupa el uso de JavaScript directo XSS / Same Origin Policy.

  2. Debe ser un subdominio disjunto si necesita evitar que lea cookies (como las ID de sesión). Es decir, puede ser inseguro.example.com si tiene su sitio principal en www.example.com, pero en ese caso no debe permitir que su sitio responda solo con ‘example.com’. no se puede evitar que las cookies de example.com se hereden en insecure.example.com en IE. Práctica recomendada: redirija todos los accesos a example.com a www.example.com.

  3. Debe ser un dominio completamente diferente si necesita evitar el uso forzado de cookies: es decir, insecure.example.com puede escribir una cookie que será leída por www.example.com, lo que podría invalidar las cookies establecidas por www. .example.com. Esta es una vulnerabilidad menos grave: la capacidad de leer las cookies generalmente lleva al secuestro de sesión, mientras que el forzado de cookies solo lleva a la denegación de servicio (ya que www.example.com no funcionará sin sus cookies).

  4. También debe servirse en una dirección IP diferente, si está preocupado por evitar el robo de cookies utilizando una vulnerabilidad en los complementos Java más antiguos, o si tiene otros servicios ejecutándose en puertos que no desearía applets para poder acceder.

Entre ellos, los navegadores y los complementos han hecho que alojar los archivos cargados de forma segura sea una terrible experiencia.

    
respondido por el bobince 16.02.2012 - 00:59
fuente
9

Desafortunadamente, en su ejemplo, Internet Explorer aún intentará detectar el tipo MIME de los primeros 256 bytes de contenido de los archivos (se llama MIME sniffing). Cita de la documentación de MSDN sobre el tema :

  

2 . Si el tipo MIME proporcionado por el servidor es conocido o ambiguo (mi nota: application/pdf es conocido), se analiza el búfer en un intento de verificar u obtener un tipo MIME del contenido real. Si se encuentra una coincidencia positiva (una de las pruebas codificadas ha sido exitosa), este tipo MIME se devuelve inmediatamente como la determinación final, anulando el servidor proporcionado Tipo MIME (este tipo de comportamiento es necesario para identificar un archivo .gif que se envía como texto / html). Durante la exploración, se determina si el búfer es predominantemente de texto o binario.

Acabo de confirmar este comportamiento utilizando el siguiente archivo PHP:

<?php header('Content-Type: application/pdf'); ?>
<html>
<p>Hello, <b>world</b></p>

Esto muestra el contenido HTML en IE8 / Win XP SP2.

Puede modificar este proceso especificando X-Content-Type-Options: nosniff encabezado HTTP en respuesta, pero se admite en IE8 + . Afortunadamente, otros navegadores confían en los encabezados HTTP y el rastreo de MIME es mucho más ligero en ellos, ver, por ejemplo, documentos de Firefox . Hay un muy buen documento técnico que documenta MIME sniffing en varios navegadores.

Si es posible, también deberías intentar verificar los bytes mágicos del contenido del archivo. También te aconsejaría que uses el encabezado Content-disposition: attachment .

    
respondido por el Krzysztof Kotowicz 15.02.2012 - 19:18
fuente
6

Detección de contenido. Su propuesta no es suficiente: será vulnerable a los ataques de detección de contenido. He escrito en otra parte sobre estrategias para prevenir los ataques de rastreo de contenido . Hay una variedad de defensas. Aquí están los principales:

  • Incluya un encabezado Content-Type: en la respuesta. Asegúrese de que incluya un tipo MIME válido (evite los tipos MIME no válidos).

  • Incluya un encabezado X-Content-Type-Options: nosniff en la respuesta. Esto desactivará los algoritmos de rastreo de contenido de IE, en versiones recientes de IE.

  • Si no pretende que el contenido se vea en el navegador, puede ayudar a configurar Content-Disposition: attachment , para que el navegador lo trate como una descarga de archivos.

Incluso estos pasos no están garantizados para ser suficiente. Por ejemplo, si el usuario utiliza IE6, seguirá siendo vulnerable.

(Si esto suena molesto, seguro que tienes razón. Culpa a la gente de Apache por incluir una configuración por defecto que rompió los estándares web, durante muchos años, e ignoró las súplicas de hacer algo al respecto. Desafortunadamente, ahora es demasiado tarde: estamos atrapados con una gran base de navegadores desplegados que hacen cosas peligrosas.)

Dominio separado. Una mejor defensa es alojar el contenido proporcionado por el usuario en un dominio separado, que se usa solo para el contenido subido por el usuario. De esa manera, un ataque exitoso de rastreo de contenido no puede atacar el contenido de su sitio. La carga de un usuario todavía puede atacar las cargas de otros usuarios, pero eso puede ser tolerable.

Verifique su lista blanca. Parece que asume que los archivos PDF y Word son inofensivos. Sin embargo, esos son dos formatos de archivo potentes y peligrosos. PDF es conocido por ser un vector. Los archivos PDF maliciosos abundan y pueden penetrar con éxito en muchos visores de PDF más antiguos. El riesgo de PDF es tan alto que Chrome toma precauciones especiales antes de permitirle descargar y ver un documento PDF en su visor de PDF. Word también es un formato de archivo poderoso y peligroso, que puede ser un host de ataques. Por esta razón, no consideraría que Word o PDF sean inofensivos.

Es posible que pueda redirigir a los usuarios a Google Docs, para ver el archivo Word / PDF en su navegador a través de Google Docs. Google convertirá el archivo Word / PDF a HTML y luego lo enviará al navegador del usuario. Esto puede o no ser aceptable en sus circunstancias.

Escanear archivos cargados en busca de virus. Le recomiendo que analice todo el contenido subido por usuarios en busca de virus, usando un escáner de virus o malware. Para archivos PDF, consulte también ¿Cómo escanear un PDF en busca de malware? . Es posible que desee escanear la carga inmediatamente cuando se carga. También puede considerar volver a escanear periódicamente los archivos antiguos (esto puede detectar un malware que no se detectó anteriormente, ya que las definiciones de antivirus / malware se actualizan).

Más información. Consulte también Lista de verificación de Mozilla para cargar archivos , en su seguro Codificación estándar. Es una lista bastante buena de buenas prácticas de seguridad.

Resumen. En resumen, la defensa más poderosa y efectiva que puede usar es colocar el contenido subido por el usuario en un dominio separado. Luego, como protección adicional, es posible que desee considerar las otras defensas enumeradas aquí.

Actualización: acabo de enterarme de un problema más con tu esquema. Al parecer, Flash ignora el encabezado Content-Type , que podría permitir la carga de un archivo SWF malicioso, que puede hacer todo lo que pueda Lo harías con un XSS. (Suspiro, estúpido Flash.) Desafortunadamente, ninguna cantidad de listas blancas puede detener este ataque. En consecuencia, parece que la única solución segura es alojar el contenido subido por el usuario en un dominio separado.

    
respondido por el D.W. 19.02.2012 - 08:41
fuente
2

Creo que las otras 2 respuestas son buenas. Pero hay otra cosa en que pensar: incluso si tuvo éxito al restringir los tipos de contenido que sirve, los documentos de Word y PDF pueden ser maliciosos por sí mismos.

Un documento PDF puede explotar cualquiera de las cientos de vulnerabilidades que existen en versiones anteriores de Adobe Reader. La mejor mitigación contra esto es escanear cada archivo cargado con detección de antivirus / malware. (Aunque todavía es una mitigación limitada debido a la naturaleza del gato y el ratón de las firmas de virus).

    
respondido por el Mark E. Haase 16.02.2012 - 17:41
fuente

Lea otras preguntas en las etiquetas