Content-Security-Policy: l'header che i plugin anti-XSS non sostituiscono
Data Pubblicazione: 15/09/2026 | | Sicurezza

Content-Security-Policy: l'header che i plugin anti-XSS non sostituiscono

La CSP è un header HTTP, non un plugin. Dice al browser da dove può caricare gli script. Report-Only prima, enforcement dopo. unsafe-inline la svuota. Un overlay anti-XSS è un altro script.

Un plugin «anti-XSS» che inietta uno script in pagina non è una Content Security Policy. È un altro script. La CSP è un header HTTP: dice al browser da dove può caricare script, stili, immagini, e se può eseguire il JavaScript scritto in chiaro nel HTML. Senza quell’header, il browser esegue ciò che trova. Con unsafe-inline dappertutto, l’header c’è e non fa il mestiere.

In breve: la Content-Security-Policy si spedisce dal server, su tutte le risposte, non solo sulla home. Serve come seconda linea contro XSS e clickjacking, non al posto della sanificazione dell’output. OWASP distingue policy strict (nonce o hash) e policy a allowlist. Report-Only si usa per misurare, poi si passa all’enforcement. Un CMS pieno di plugin inline spesso non sopravvive a una policy strict: è un dato di fatto, non un motivo per non partire.

Cosa trovi in questo articolo

  1. Cosa fa una CSP, e cosa non è

  2. Tre modi di consegnarla: uno solo è completo

  3. Strict vs allowlist: la scelta che conta

  4. Cosa si rompe su un CMS a plugin

  5. Errori da evitare

  6. In sintesi

Cosa fa una CSP, e cosa non è

OWASP, nella Content Security Policy Cheat Sheet, la inquadra come difesa in profondità lato client. Il server inietta l’header; il browser rifiuta chiamate che caricherebbero contenuto non previsto. Non elimina le vulnerabilità. Le rende più difficili da sfruttare.

Cinque mestieri, sempre da quella scheda:

Direttiva / effettoCosa blocca, se è scritta beneCosa non blocca da sola
Niente script inlineUn tag script iniettato nella paginaUn XSS che passa da un file JS già autorizzato
Niente script da origini arbitrarieUno script caricato da un host non in elencoUn CDN compromesso se quel CDN è in allowlist
Niente compilazione di testo in JavaScript a runtimeTesto trasformato in codice eseguibile dal browserLogica insicura già nel bundle
form-actionUn form di phishing iniettato che posta altroveUn form legittimo mal protetto lato server
frame-ancestorsClickjacking e parte degli xs-leaks da iframeSostituisce X-Frame-Options; non sostituisce CSRF

OWASP è esplicita: anche su un sito statico, senza input utente, una CSP può imporre Subresource Integrity sugli script di terzi. Se il fornitore di analytics viene compromesso, il browser non esegue il file alterato, a patto che l’hash non torni. Resta una seconda linea. La prima è ancora la prevenzione XSS descritta nell’altra cheat sheet OWASP. Un WAF, per confronto, filtra richieste: è un altro strato, trattato in WAF: cosa blocca e cosa non può risolvere. La CSP non è un WAF. Non è un overlay. Non è un certificato: il transito sta nella checklist TLS.

Questo pezzo sta nel cluster Sicurezza.

Tre modi di consegnarla: uno solo è completo

OWASP elenca tre veicoli. MDN, nella guida Content Security Policy, coincide sul preferito.

VeicoloEnforcementLimite
Content-Security-Policy (header di risposta)Nessuno rilevante: è il modo standard. Va su tutte le risposte, non solo l’index
Content-Security-Policy-Report-OnlyNo: solo report in console e all’endpointServe a misurare prima di rompere il sito. Non protegge
Elemento meta http-equiv Content-Security-PolicyParzialeOWASP avverte: non supporta l’insieme completo delle direttive (in particolare reporting e alcune di navigazione). Non è il canale da produzione

Report-Only e Policy si possono spedire insieme: si misura la nuova, si tiene in vita la vecchia. L’endpoint di report (report-uri / report-to) è parte del lavoro, non un extra. Senza report si naviga alla cieca, e il primo giorno di enforcement è il giorno in cui il checkout smette di parlare con il PSP.

Strict vs allowlist: la scelta che conta

OWASP divide le policy in due famiglie.

Strict CSP. Gli script inline autorizzati portano un nonce (valore casuale per risposta) o un hash del contenuto. strict-dynamic consente a uno script già fidato di caricarne altri, senza tenere una lista di host. È il modello che resiste meglio a un XSS classico: l’attaccante non conosce il nonce della risposta. Il nonce va generato per ogni documento. Riutilizzarlo, o metterlo in cache con la pagina, lo brucia.

Allowlist (granulare). Si elencano origini: script-src 'self' https://cdn.example. È più facile da spiegare in una riunione. È più fragile: ogni host in lista è una porta. Un JSONP su quel CDN, o un file che l’attaccante riesce a far ospitare lì, passa. OWASP la considera accettabile in transizione, non come obiettivo.

Una policy «base» non-strict, nella stessa cheat sheet, usa 'self', blocca object-src, imposta frame-ancestors 'none' o il proprio origine, e può aggiungere upgrade-insecure-requests. Quest’ultima chiede al browser di promuovere HTTP in HTTPS: è un complemento al redirect lato server, non un sostituto. Il lucchetto, da solo, non è una CSP.

Cosa si rompe su un CMS a plugin

Il costo vero di una CSP non è l’header. È l’inventario di ciò che la pagina già esegue. Su un CMS a plugin il conto è questo, e non è una stima di traffico: è ciò che si vede in Report-Only in una settimana.

Sintomo in reportCosa sta succedendoCosa non fare
Blocco di script-src su inlineUn modulo scrive JavaScript inline in pagina: analytics, chat, pixel, overlayAggiungere 'unsafe-inline' e dichiarare il lavoro finito
Blocco su un host sconosciutoUn plugin carica JS da un dominio che non era nel preventivoAllargare l’allowlist «così non si rompe». Si misura, si decide, o si toglie il plugin
Blocco della compilazione a runtimeUna libreria vecchia compila template in JavaScript a runtimeRiattivare quella compilazione per sempre. Si aggiorna la libreria o si isola
Checkout o area admin mutiform-action o connect-src non includono PSP, API, WebSocketSpegnere la CSP. Si aggiunge l’origine giusta, non *
Frame del sito su un partnerframe-ancestors 'none' è corretto per il sito pubblico, sbagliato se un partner deve embeddareCopiare *. Si elenca l’origine del partner

Il contributo, qui, non è una policy da copiare. È l’ordine: Report-Only su staging, una settimana di report, inventario, nonce dove il tema lo consente, enforcement a pezzi (default-src stretto, script dopo). Un overlay che promette «conformità» aggiungendo un file JS è il contrario di una CSP: allarga la superficie. Il costo nascosto di quei moduli sta in il costo nascosto dei plugin; le patch, in ritmo delle patch. La CSP non li sostituisce.

Errori da evitare

  • Spedire 'unsafe-inline' su script-src e chiamarla una CSP.

  • Mettere la policy solo in un meta http-equiv e credere di avere reporting e direttive complete.

  • Enforcement in produzione il primo giorno, senza Report-Only.

  • Un nonce messo in cache con l’HTML. Non è più un nonce.

  • Confondere CSP e WAF, o CSP e certificato TLS.

  • Comprare un overlay XSS e togliere l’header «perché adesso c’è il plugin».

In sintesi

La Content-Security-Policy è un header, su tutte le risposte. Dice al browser cosa può eseguire. OWASP la vuole strict, con nonce o hash, e Report-Only prima dell’enforcement. unsafe-inline la svuota. Un plugin che inietta script è un problema da inventariare, non una soluzione. XSS si previene nel codice; la CSP è la seconda linea, se la si scrive.

Fonti

Immagine di copertina: tastiera e schermo. La Content-Security-Policy si pubblica nell’header HTTP, non in un plugin. Foto di Thomas Lefebvre, Unsplash via Wikimedia Commons, licenza CC0.

Questo contenuto è stato realizzato con il supporto di sistemi di intelligenza artificiale e successivamente verificato secondo le linee editoriali della redazione.

Domande Frequenti

Un header HTTP (Content-Security-Policy) con cui il server dice al browser quali origini e quali script può eseguire. OWASP la tratta come difesa in profondità contro XSS e clickjacking (frame-ancestors). Non sostituisce la sanificazione dell'output.
No. Un plugin che inietta JavaScript in pagina è un altro script, spesso in conflitto con una policy strict. La CSP si spedisce dal server su tutte le risposte. Un overlay non è un header.
Autorizza gli script scritti in chiaro nel HTML. È la condizione in cui un XSS classico torna eseguibile. OWASP indica come obiettivo una policy strict con nonce o hash, non una allowlist piena di unsafe-inline.
Report-Only prima: i report arrivano, la pagina non si rompe. Poi enforcement. OWASP elenca anche il meta http-equiv: non copre l'insieme completo delle direttive e non è il canale da produzione.
No. Il WAF filtra richieste. TLS cifra il transito. La CSP vincola il browser su ciò che la pagina può caricare. Sono tre strati. Confonderli è il modo per spegnerne uno credendo di averlo coperto.

Potrebbe interessarti anche...