Todas las guías
Severidad MediaEncabezados de seguridad

MIME sniffing y X-Content-Type-Options: nosniff explicado

Los navegadores pueden "husmear" el contenido real de una respuesta para decidir cómo tratarla, incluso cuando tu servidor envía el Content-Type incorrecto. El encabezado X-Content-Type-Options: nosniff indica al navegador que confíe en el tipo declarado y rechace promover archivos — como una imagen subida — a script ejecutable.

Qué es

El MIME sniffing es una heurística del navegador que inspecciona los primeros bytes de una respuesta para inferir su tipo de contenido cuando el encabezado Content-Type del servidor está ausente o no coincide con el contenido. Por ejemplo, un archivo declarado como text/plain que empieza con <script> podría reclasificarse y ejecutarse como HTML.

X-Content-Type-Options es un encabezado de respuesta de valor único: X-Content-Type-Options: nosniff. Cuando está presente, los navegadores se niegan a promover una respuesta a un tipo MIME diferente: un archivo subido servido como application/octet-stream permanece binario, nunca se convierte en script o hoja de estilos ejecutable.

Por qué importa

El contenido generado por usuarios es el principal riesgo. Si tu app permite subir archivos y los sirves desde el mismo origen que tu app, un archivo HTML malicioso disfrazado de imagen puede ejecutarse en los navegadores de las víctimas cuando se husmea, un XSS almacenado a través de carga de archivos, incluso cuando validas las extensiones en el servidor.

Sin nosniff, los navegadores también pueden ejecutar hojas de estilo obtenidas de fuentes inesperadas. Una hoja de estilo que se ejecuta como script crea un vector de exfiltración de datos entre orígenes cuando se combina con otras configuraciones incorrectas. nosniff es una salvaguarda global de bajo costo que refuerza cada límite de contenido de tu app.

Cómo solucionarlo

Agrega el encabezado globalmente en Next.js

Define X-Content-Type-Options: nosniff en next.config.js para que se aplique a todas las respuestas, incluidas las rutas de API y las rutas de archivos estáticos.

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: "/:path*",
        headers: [
          { key: "X-Content-Type-Options", value: "nosniff" },
        ],
      },
    ];
  },
};
Configúralo en nginx

Agrega la directiva en tu bloque server para que se aplique a todas las respuestas enviadas a través de nginx.

add_header X-Content-Type-Options "nosniff" always;
Declara siempre un Content-Type preciso

nosniff es más eficaz cuando cada respuesta también lleva un encabezado Content-Type correcto. Para archivos subidos por usuarios, sírvelos con un tipo apropiado y desde un origen o dominio de almacenamiento separado, no el mismo origen que tu app, para que incluso si un archivo se ejecuta no pueda acceder a las cookies de sesión de tus usuarios.

Valida las cargas por contenido, no solo por extensión

Las comprobaciones de extensión pueden eludirse. Usa una biblioteca como file-type (npm) para inspeccionar los bytes mágicos del archivo en el servidor y rechaza cualquier cosa que no coincida con una lista de tipos seguros antes de que llegue a la capa de almacenamiento.

import { fileTypeFromBuffer } from "file-type";

const ALLOWED = new Set(["image/jpeg", "image/png", "image/webp", "image/gif"]);

async function validateUpload(buffer: Buffer): Promise<void> {
  const type = await fileTypeFromBuffer(buffer);
  if (!type || !ALLOWED.has(type.mime)) {
    throw new Error("Upload rejected: unsupported file type");
  }
}

Preguntas frecuentes

¿Qué severidad reporta AppSafe por un encabezado X-Content-Type-Options ausente?

Media. El encabezado es una medida de refuerzo de bajo esfuerzo — una línea de configuración —, por lo que omitirlo es una brecha clara, pero la explotación activa requiere un vector de carga o inyección separado.

¿nosniff afecta las cargas de página normales?

En la práctica, no. nosniff solo bloquea la promoción a un tipo más peligroso. Tu HTML, CSS y JavaScript ya se sirven con los tipos correctos, por lo que se cargan con normalidad.

¿Sigue siendo relevante X-Content-Type-Options ahora que los navegadores modernos son más inteligentes?

Sí. El comportamiento de sniffing varía entre motores y versiones, y el encabezado es la única garantía portable. Todos los navegadores actuales (Chrome, Firefox, Safari, Edge) respetan nosniff.

¿Tu app está afectada?

AppSafe verifica este y docenas de problemas más en un solo escaneo gratis.

Escanear mi app gratis