Gli header di risposta HTTP sono istruzioni che il server invia al browser insieme alla pagina. Alcuni servono alla cache, altri al tipo di contenuto, e un gruppo specifico serve a limitare cosa il browser può fare con quella pagina. Configurarli costa poche righe e chiude intere categorie di problemi. Vale per qualunque sito, compreso uno statico.
Strict-Transport-Security (HSTS)
Anche se il tuo sito reindirizza da HTTP a HTTPS, la prima richiesta di un utente che digita l'indirizzo senza prefisso può partire in chiaro. HSTS dice al browser: per questo dominio usa sempre HTTPS, per un certo periodo, senza nemmeno tentare HTTP.
Strict-Transport-Security: max-age=31536000; includeSubDomains
max-ageè la durata in secondi (qui un anno).includeSubDomainsestende la regola a tutti i sottodomini.
Prima di attivare includeSubDomains, verifica che ogni sottodominio funzioni in HTTPS: un vecchio sottodominio interno solo HTTP diventerebbe irraggiungibile. Una strategia prudente è partire con un max-age breve, controllare che tutto funzioni e poi aumentarlo. Esiste anche la direttiva preload, che permette di inserire il dominio in un elenco integrato nei browser; è una scelta difficile da annullare, quindi va fatta solo quando sei sicuro.
X-Content-Type-Options
I browser, in passato, cercavano di "indovinare" il tipo di un file guardandone il contenuto, ignorando quello dichiarato dal server. Questo comportamento può trasformare un file caricato come testo in uno script eseguito.
X-Content-Type-Options: nosniff
Con nosniff il browser si fida solo del Content-Type dichiarato. È un header senza controindicazioni, a patto che il server indichi tipi corretti per CSS e JavaScript.
Protezione dal clickjacking
Il clickjacking consiste nel caricare il tuo sito in un iframe invisibile su un'altra pagina e indurre l'utente a cliccare su pulsanti che non vede. La difesa moderna è la direttiva frame-ancestors della Content Security Policy:
Content-Security-Policy: frame-ancestors 'self'
Con 'self' la pagina può essere incorniciata solo dal tuo stesso sito; con 'none' da nessuno. Il vecchio header X-Frame-Options (con i valori DENY o SAMEORIGIN) svolge lo stesso compito ed è ancora utile come rinforzo per browser datati.
Referrer-Policy
Quando un utente clicca un link verso un altro sito, il browser può inviare l'indirizzo della pagina di provenienza nell'header Referer. Se i tuoi URL contengono informazioni sensibili, come identificativi o parametri di ricerca, queste finiscono a terzi.
Referrer-Policy: strict-origin-when-cross-origin
Questo valore invia l'URL completo per i link interni, solo il dominio verso altri siti e nulla quando si passa da HTTPS a HTTP. È anche il comportamento predefinito di molti browser moderni, ma dichiararlo rende la scelta esplicita e uniforme. Per pagine particolarmente riservate puoi usare no-referrer.
Permissions-Policy
Questo header permette di disattivare funzioni del browser che il sito non usa: fotocamera, microfono, geolocalizzazione, pagamenti e altre ancora. Se un giorno uno script di terze parti tentasse di usarle, il browser rifiuterebbe.
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
Le parentesi vuote significano "nessuna origine autorizzata". Se una funzione ti serve, puoi limitarla al tuo dominio con geolocation=(self).
Content-Security-Policy
È l'header più potente e il più delicato: definisce da quali origini la pagina può caricare script, stili, immagini e altre risorse, ed è una difesa fondamentale contro il cross-site scripting. Merita una trattazione a parte; qui basta sapere che va introdotto gradualmente, partendo dalla modalità di sola segnalazione.
Header da rimuovere
La sicurezza riguarda anche ciò che non invii. Header come Server con il numero di versione esatto o X-Powered-By con il linguaggio e la versione del backend non servono agli utenti e forniscono informazioni a chi cerca software vulnerabile. Molti server e framework permettono di eliminarli o ridurli con una sola impostazione.
Un esempio completo
Su molti hosting statici gli header si dichiarano in un file di configurazione. Una configurazione di partenza ragionevole:
/*
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN
Con nginx l'equivalente si scrive con la direttiva add_header, ricordando il parametro always per applicarlo anche alle risposte di errore:
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Come verificare
- Apri gli strumenti per sviluppatori, scheda Rete, seleziona il documento principale e controlla gli header di risposta.
- Da terminale,
curl -I https://tuosito.itmostra solo gli header. - Esistono servizi online che analizzano gli header di un sito e segnalano quelli mancanti: utili per un controllo rapido, ma interpreta i risultati con giudizio.
Ricontrolla dopo ogni cambio di hosting, CDN o configurazione: è facile perdere gli header durante una migrazione.
In sintesi
- HSTS forza HTTPS; attiva
includeSubDomainsepreloadsolo dopo le verifiche. X-Content-Type-Options: nosniffimpedisce al browser di reinterpretare i tipi di file.frame-ancestors(eX-Frame-Options) protegge dal clickjacking.Referrer-PolicyePermissions-Policylimitano dati inviati e funzioni disponibili.- Rimuovi gli header che rivelano versioni del software e verifica dopo ogni migrazione.