X-Content-Type-Options
Uso
El MIME sniffing es un comportamiento del navegador por el que este inspecciona el contenido de una respuesta y anula el Content-Type declarado según los patrones encontrados en el cuerpo de la respuesta. Aunque se concibió como una comodidad para los servidores mal configurados, el MIME sniffing abre un agujero de seguridad: un atacante sube un archivo disfrazado de imagen, el navegador detecta el contenido como HTML o JavaScript y se ejecuta un ataque de cross-site scripting.
La cabecera X-Content-Type-Options cierra ese agujero. Cuando se fija en nosniff, el navegador sigue estrictamente la cabecera Content-Type y se niega a cargar los recursos cuyo tipo declarado no coincide con el tipo esperado. En los destinos de estilo, el navegador bloquea la respuesta salvo que el Content-Type sea text/css. En los destinos de script, el navegador bloquea la respuesta salvo que el Content-Type sea un tipo MIME de JavaScript válido.
Esta cabecera está ampliamente desplegada como medida estándar de fortalecimiento de la seguridad y se recomienda junto con Content-Security-Policy y X-Frame-Options para lograr una defensa en profundidad.
nosniff
El valor nosniff es el único valor definido. Establecer esta directiva impide que el navegador desvíe una respuesta de su Content-Type declarado mediante MIME sniffing.
Ejemplo
Un servidor que entrega la respuesta de una API JSON con el MIME sniffing desactivado, de modo que el navegador trate la respuesta estrictamente como JSON:
Content-Type: application/json
X-Content-Type-Options: nosniff
Un archivo CSS servido con el Content-Type correcto y protección frente al sniffing, lo que impide que el navegador reinterprete el archivo:
Content-Type: text/css
X-Content-Type-Options: nosniff
Diagnóstico
Los recursos bloqueados por nosniff producen errores en la consola que señalan una discrepancia de tipo MIME entre el Content-Type declarado y el tipo esperado para el destino del recurso.
Script bloqueado por discrepancia de tipo MIME. El navegador registra Refused to execute script from ’…’ because its MIME type (‘text/plain’) is not executable. Esto ocurre cuando el servidor envía un archivo JavaScript con un Content-Type distinto de un tipo MIME de JavaScript válido (text/javascript, application/javascript). Corrija la configuración del servidor. En nginx, confirme que include mime.types; aparece en el bloque http. En Apache, verifique que AddType text/javascript .js existe en la configuración o en el .htaccess.
CSS no aplicado por un tipo MIME incorrecto con nosniff. La consola muestra Refused to apply style from ’…’ because its MIME type (‘text/html’) is not a supported stylesheet MIME type. El servidor está enviando los archivos CSS como text/html o text/plain en lugar de text/css. En nginx, añadir types { text/css css; } o incluir el archivo mime.types predeterminado resuelve la discrepancia. En Apache, añada AddType text/css .css a la configuración del servidor.
El servidor envía un Content-Type incorrecto para los archivos estáticos. Los servidores, las CDN o el almacenamiento de objetos (S3, GCS) mal configurados suelen servir los archivos estáticos como application/octet-stream o text/plain. Revise el Content-Type de cada recurso en la pestaña Network de DevTools seleccionando la solicitud e inspeccionando las cabeceras de respuesta. En S3, establezca los metadatos ContentType al subir el archivo. En los recursos servidos por una CDN, verifique que el origen devuelve el tipo correcto, ya que la mayoría de las CDN transmiten sin cambios el Content-Type del origen.
Diagnóstico de recursos bloqueados en la consola de DevTools. Abra la pestaña Console y filtre los errores relacionados con MIME. Cada mensaje de recurso bloqueado incluye la URL, el tipo MIME declarado y el tipo esperado. Contrástelo con la pestaña Network: seleccione la solicitud bloqueada, abra el panel Headers y revise la cabecera de respuesta Content-Type. La solución pasa siempre por corregir el Content-Type en el servidor, no por eliminar la cabecera nosniff.
Configuración
Aplique nosniff a todas las respuestas. La sobrecarga es insignificante y la protección cubre scripts, estilos y otros subrecursos.
nginx:
add_header X-Content-Type-Options nosniff always;
Apache:
Header always set X-Content-Type-Options nosniff
IIS (web.config):
<code class="language-xml"><customHeaders>
<add name="X-Content-Type-Options"
value="nosniff" />
</customHeaders>