Basi della sicurezza
Intestazioni di sicurezza mancanti: quando contano
Le intestazioni di sicurezza mancanti sono il rilievo che il nostro scanner stampa più spesso. Da cosa proteggono e quando sono la riga meno urgente.

In breve
- Le intestazioni di sicurezza mancanti sono il rilievo più comune che esista e, da sole, dicono quasi nulla su chi possa arrivare ai tuoi dati.
- Abbiamo scansionato 30.998 app in produzione. Due su tre di quelle a cui mancavano intestazioni non avevano nient’altro che non andasse.
- Vale comunque la pena sistemarle, e vengono dopo le cose che decidono chi può leggere il tuo database.
- Su alcuni domini dei builder non puoi impostarle da solo, e lasciarle lì è una risposta ragionevole.
La scansione torna indietro e quasi tutte le righe sono verdi. Una è ambra: mancano alcune intestazioni di sicurezza del browser. È l’unica cosa colorata della pagina, quindi sembra la prima di cui occuparsi.
Ecco la parte che la maggior parte dei consigli su questo tema sbaglia. Le intestazioni di sicurezza mancanti sono il rilievo che stampiamo più spesso e, da sole, non ti dicono quasi nulla su chi possa arrivare ai tuoi dati. Trattarle come una violazione significa o sistemarle nel panico prima delle cose che davvero decidono chi legge il tuo database, o imparare che le righe ambra sono rumore, il che è peggio.
Tra il 12 e il 14 agosto 2026 abbiamo passato gli stessi nove controlli esterni su 30.998 app in produzione costruite con Lovable, Bolt, v0, Replit e Base44. Tra le app da cui questo controllo ha ottenuto una risposta, a 30.756 su 30.981 mancava almeno un’intestazione. I numeri completi sono nel nostro rapporto di scansione.
Le intestazioni di sicurezza mancanti sono un problema?
È una lacuna vera ed è quasi sempre la riga meno urgente del tuo rapporto.
Un’intestazione di sicurezza è una breve istruzione che il tuo server allega a ogni pagina che invia, rivolta al browser di chi visita e non alla persona. Non lasciare che un altro sito metta questa pagina dentro una cornice. Non indovinare che tipo di file sia questo. Non passare il mio indirizzo completo quando qualcuno clicca verso l’esterno. Sono appunti per un aiutante che fa quello che gli dice qualunque sito.
Il resto del tuo rapporto parla di serrature. Se Row Level Security è attivo, se c’è una chiave segreta nel tuo codice, se un bucket di storage elenca il suo contenuto: sono queste cose a decidere chi può arrivare ai tuoi dati. Gli appunti e le serrature si vogliono entrambi, e l’appunto che non hai mai scritto non è il motivo per cui si perde un database.
La nostra valutazione la vede così. Un’intestazione mancante toglie cinque punti su cento e non mette alcun tetto, quindi un’app il cui unico rilievo è questo esce con 95 e voto A.
Cosa abbiamo trovato su 30.998 app
Le intestazioni mancanti sono comparse quasi ovunque, e si sono mosse a malapena con il resto del rapporto.
25.821 di quelle app hanno ottenuto una risposta da tutti e nove i controlli, ed è il gruppo in cui "non c’era nient’altro" significa qualcosa. Tra queste, a 25.606 mancava almeno un’intestazione e 215 le avevano tutte e cinque.
Delle 25.606 app a cui mancava almeno un’intestazione, 17.043 non avevano nient’altro che non andasse. Due su tre. Era l’unico problema del loro rapporto.
Adesso leggi l’altra riga, che è la parte che ci ha sorpreso. Delle 215 app che avevano tutte e cinque le intestazioni impostate, 145 avevano qualcos’altro che non andava. È un tasso di problemi veri più alto che tra le app con intestazioni mancanti, non più basso.
Non abbiamo misurato il perché, e la lettura onesta è stretta: qualunque cosa queste scansioni abbiano trovato, il rilievo sulle intestazioni non l’ha previsto. Un’app con un insieme perfetto di intestazioni non era un’app più sicura nei nostri dati. La spiegazione più probabile è che impostare le intestazioni implichi che qualcuno abbia configurato un hosting vero, il che di solito implica un’app più grande con più cose da sbagliare, ma è un’ipotesi e non l’abbiamo verificata.
Se vuoi vedere quali di queste righe produce la tua app, la scansione è gratuita, richiede circa 20 secondi e non serve alcun account: scansiona la tua app.
Cosa fa davvero ogni intestazione
Ognuna spegne un comportamento del browser che è attivo di default.
| Intestazione | Cosa dice al browser | Cosa consente la sua assenza |
|---|---|---|
Content-Security-Policy | Da quali posti questa pagina può caricare codice e stili | Uno script iniettato può mandare dati dove vuole |
Strict-Transport-Security | Torna sempre in HTTPS, mai in HTTP semplice | Una visita su una rete non fidata può essere spinta giù a HTTP semplice |
X-Frame-Options | Non lasciare che un altro sito mostri questa pagina dentro una cornice | La tua pagina può essere caricata in modo invisibile dentro quella di un altro |
X-Content-Type-Options | Fidati del tipo di file che ti ho dato e non indovinarlo dal contenuto | Un file caricato da qualcuno può essere servito come un tipo di file diverso |
Referrer-Policy | Quanta parte di questo indirizzo passare quando qualcuno clicca verso l’esterno | URL complete, con dentro tutto quello che contengono, arrivano a server di terzi |
Due di queste si sovrappongono, e lo scanner ne tiene conto. Una
Content-Security-Policy che contiene frame-ancestors fa lo stesso lavoro di
X-Frame-Options, quindi il nostro controllo ne conta una qualsiasi delle due e
non le pretende entrambe.
Quando un’intestazione mancante è tutto il problema
Quando la tua app ha qualcosa che vale la pena cliccare mentre si è loggati.
È il caso del clickjacking, ed è l’unico che funziona senza nessun altro errore. Qualcuno carica la tua app dentro una cornice invisibile su una pagina che controlla e mette i propri pulsanti sopra i tuoi, così chi è già loggato clicca su quella che sembra la sua pagina e colpisce invece un comando tuo: il pulsante che cancella un account, approva un bonifico o cambia un indirizzo email.
Chi visita è loggato, quindi l’azione porta con sé la sua sessione. Non serve che nulla del tuo database sia configurato male. A rendere possibile la cosa è che al browser non è mai stato detto di rifiutare.
Referrer-Policy ha una versione più piccola della stessa forma. Se una tua
pagina in sessione porta qualcosa di identificativo nell’URL e rimanda a un
hosting di immagini o a uno script di analytics, l’indirizzo intero viaggia con
il clic. Chi gestisce quell’altro server vede dov’era il tuo utente.
Le altre tre sono condizionate. Contano quando qualcos’altro è già andato
storto, e il loro compito è tenerlo piccolo. Una Content-Security-Policy
limita cosa uno script iniettato può fare con il suo accesso.
X-Content-Type-Options conta se degli sconosciuti possono caricarti file.
Strict-Transport-Security copre chi usa la tua app su una rete che non
controlla.
Mi servono le intestazioni di sicurezza?
Sì. Costano poco, e vengono dopo i rilievi che decidono chi può leggere il tuo database.
L’ordine che discende dalla misura qui sopra: prima tutto quello che nel tuo rapporto è critico o alto, le intestazioni dopo. Se nel tuo rapporto c’è solo questa riga, come per 17.043 delle app che abbiamo scansionato, allora le intestazioni stanno in cima alla tua lista per esclusione.
Due delle cinque non costano nulla da mettere a posto.
X-Content-Type-Options: nosniff e
Referrer-Policy: strict-origin-when-cross-origin sono una riga ciascuna, non
hanno un valore sbagliato da scegliere e non possono rompere un’app che
funziona. Anche X-Frame-Options: DENY è una riga, e vale la pena guardarla
prima se incorpori la tua app da qualche parte di proposito.
Content-Security-Policy è quella che richiede lavoro vero. Un primo tentativo
di solito blocca qualcosa che serviva alla tua stessa pagina, e il sintomo è una
funzione che smette di funzionare senza dire niente. Mandala in produzione come
Content-Security-Policy-Report-Only, che ti dice cosa avrebbe bloccato senza
bloccare nulla, e leggi una settimana di rapporti prima di attivarla.
Come aggiungerle
In ciò che serve davvero la tua app a internet, che spesso non è il posto dove la costruisci.
La maggior parte dei builder distribuisce su un hosting che è padrone della
risposta, quindi l’impostazione vive lì. Su Vercel è headers dentro
vercel.json. Su Netlify e Cloudflare Pages è un file _headers nella radice
di quello che pubblichi. Dietro il proxy di Cloudflare è una Transform Rule. Se
gestisci un server tuo, è la tua configurazione nginx o Caddy.
La cosa da sapere sulle intestazioni una volta impostate è che vanno via senza che nessuno le tocchi. Passare a un dominio tuo, mettere un proxy davanti, cambiare hosting, toccare la configurazione del framework: le intestazioni che hai aggiunto vivono in uno di quei posti, e ognuna di quelle mosse può lasciarsele indietro. Nulla te lo dice. La pagina continua a funzionare e l’impostazione non c’è più.
È per questo genere di cose che esiste Reeve Monitor. Ripassa il controllo completo ogni ora su un massimo di tre app, sorveglia la raggiungibilità ogni 60 secondi e ti avvisa quando un risultato cambia, invece di aspettare che tu guardi. Monitor sorveglia e nient’altro, quindi se vuoi anche una copia del tuo database da qualche parte dove il tuo builder non arriva, quello è Care, e copre Supabase.
Cosa fare adesso
Cosa fare
- Leggi prima il resto del rapporto. Se c’è qualcosa segnato come critico o alto, il lavoro è quello, e le intestazioni aspettano.
- Metti oggi
X-Content-Type-Options: nosniffeReferrer-Policy: strict-origin-when-cross-origin. Una riga ciascuna, niente da decidere, niente da rompere. - Metti
X-Frame-Options: DENYse le persone fanno il login nella tua app e possono fare qualcosa di pesante con un solo clic. - Tieni
Content-Security-Policyper ultima e partì in modalità report-only, così scopri prima tu dei tuoi visitatori cosa rompe. - Se stai su un sottodominio di un builder senza impostazione per le intestazioni, lascia stare il rilievo. Non è ancora tuo.
- Ricontrollale dopo che hai cambiato dominio, aggiunto un proxy o cambiato hosting. È allora che spariscono.
Le intestazioni valgono un pomeriggio tranquillo una volta che il resto del rapporto è pulito. Se preferisci percorrere tutta la lista in ordine, la checklist di sicurezza in 10 minuti copre cosa spegnere in un’app appena lanciata, e i rilievi che davvero decidono chi legge il tuo database sono i primi da togliere di mezzo.
FAQ
La scansione dice che mancano intestazioni di sicurezza. La mia app è stata violata?
No. Un’intestazione mancante è un’impostazione che non è mai stata attivata, e non è la prova che sia successo qualcosa. Nel rilievo non c’è nessuno che sia arrivato ai tuoi dati o al tuo account. Descrive un’istruzione che il tuo sito potrebbe dare ai browser che lo visitano e che al momento non dà.
Quale intestazione di sicurezza dovrei mettere per prima?
X-Content-Type-Options e Referrer-Policy, perché sono entrambe una riga sola, nessuna delle due ha un valore sbagliato da scegliere e nessuna può rompere un’app che funziona. Poi X-Frame-Options, se le persone fanno il login nella tua app. Poi Strict-Transport-Security. Content-Security-Policy per ultima, perché è l’unica delle cinque che richiede vero ragionamento e l’unica che può impedire ai tuoi script di girare.
Sono sul dominio predefinito del mio builder e non c’è nessuna impostazione per le intestazioni. E adesso?
Lasciale stare. Quando la tua app viene servita da un sottodominio della piattaforma, le intestazioni di risposta sono una scelta della piattaforma e non tua, e non esiste nessun file che tu possa aggiungere per cambiarle. Collega un dominio tuo se vuoi il controllo su questo, perché è il dominio a permetterti di mettere un hosting tuo o un proxy davanti all’app. Fino ad allora, metti l’impegno sui rilievi che tocca a te sistemare.
Una Content-Security-Policy può rompere la mia app?
Sì, ed è il risultato normale di un primo tentativo. Una policy che non consente gli script inline fermerà gli script inline, compresi quelli generati dal tuo builder, e la pagina resta bianca o perde una funzione, con un errore visibile solo nella console del browser. Parti con Content-Security-Policy-Report-Only, che segnala cosa avrebbe bloccato senza bloccare nulla, e leggi i rapporti per una settimana prima di attivarla sul serio.
Le intestazioni di sicurezza aiutano se il mio database è leggibile da chiunque?
No. Le intestazioni sono istruzioni per i browser che visitano il tuo sito, e chi legge il tuo database direttamente non sta usando un browser né visitando il tuo sito. Quella richiesta va dritta al tuo fornitore di database e non tocca mai le tue pagine, quindi nessuna intestazione messa lì la riguarda. Quello lo decide Row Level Security.