Tutte le guide
Gravità MedioHeader di sicurezza

MIME sniffing e X-Content-Type-Options: nosniff spiegato

I browser possono "annusare" il contenuto reale di una risposta per decidere come gestirlo, anche quando il server invia il Content-Type errato. L'header X-Content-Type-Options: nosniff indica al browser di fidarsi del tipo dichiarato e di rifiutare di promuovere i file — come un'immagine caricata — a script eseguibile.

Che cos'è

Il MIME sniffing è un'euristica del browser che ispeziona i primi byte di una risposta per dedurne il tipo di contenuto quando l'header Content-Type del server è assente o non corrisponde al contenuto. Ad esempio, un file dichiarato come text/plain che inizia con <script> potrebbe essere riclassificato ed eseguito come HTML.

X-Content-Type-Options è un header di risposta a valore singolo: X-Content-Type-Options: nosniff. Quando presente, i browser si rifiutano di promuovere una risposta a un tipo MIME diverso — un file caricato servito come application/octet-stream rimane binario e non diventa mai uno script o foglio di stile eseguibile.

Perché è importante

I contenuti generati dagli utenti sono il rischio principale. Se la tua app consente l'upload di file e li serve dalla stessa origin dell'app, un file HTML malevolo mascherato da immagine può eseguirsi nei browser delle vittime quando viene rilevato tramite sniffing — un XSS memorizzato tramite upload di file, anche quando validi le estensioni lato server.

Senza nosniff, i browser possono anche eseguire fogli di stile recuperati da fonti inaspettate. Un foglio di stile eseguito come script crea un vettore di esfiltrazione di dati cross-origin combinato con altre configurazioni errate. nosniff è una salvaguardia globale a basso costo che rafforza ogni confine di contenuto della tua app.

Come risolverlo

Aggiungere l'header globalmente in Next.js

Imposta X-Content-Type-Options: nosniff in next.config.js in modo che si applichi a tutte le risposte, incluse le route API e le route di file statici.

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

Aggiungi la direttiva nel tuo blocco server in modo che si applichi a tutte le risposte inoltrate tramite nginx.

add_header X-Content-Type-Options "nosniff" always;
Dichiarare sempre un Content-Type accurato

nosniff è più efficace quando ogni risposta porta anche un header Content-Type corretto. Per i file caricati dagli utenti, servili con un tipo appropriato e da un'origin o dominio di storage separati — non la stessa origin dell'app — in modo che anche se un file venisse eseguito non possa accedere ai cookie di sessione dei tuoi utenti.

Validare gli upload per contenuto, non solo per estensione

I controlli sull'estensione possono essere aggirati. Usa una libreria come file-type (npm) per ispezionare i magic byte del file lato server e rifiuta qualsiasi cosa non corrisponda a una lista di tipi sicuri consentiti.

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");
  }
}

FAQ

Quale severità segnala AppSafe per un header X-Content-Type-Options mancante?

Media. L'header è una misura di hardening a bassa frizione — una riga di configurazione —, quindi ometterlo è una lacuna evidente, ma lo sfruttamento attivo richiede un vettore di upload o iniezione separato.

nosniff influisce sui normali caricamenti di pagina?

In pratica no. nosniff blocca solo la promozione a un tipo più pericoloso. Il tuo HTML, CSS e JavaScript vengono già serviti con i tipi corretti e si caricano normalmente.

X-Content-Type-Options è ancora rilevante ora che i browser moderni sono più intelligenti?

Sì. Il comportamento di sniffing varia tra engine e versioni, e l'header è l'unica garanzia portabile. Tutti i browser attuali (Chrome, Firefox, Safari, Edge) rispettano nosniff.

La tua app è interessata?

AppSafe controlla questo e decine di altri problemi in un'unica scansione gratuita.

Scansiona la mia app gratis