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
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" },
],
},
];
},
};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;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.
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 gratisGuide correlate
Content-Security-Policy (CSP): cos'è e come aggiungerla
L'header che impedisce l'esecuzione degli script iniettati.
Clickjacking e X-Frame-Options: tieni le tue pagine fuori dagli iframe
Un header impedisce ai malintenzionati di sovrapporre la tua app dentro un iframe.
Indici di directory aperti: quando il tuo file server elenca tutto
Un file server che elenca il proprio contenuto regala agli attaccanti un inventario gratuito.