Content Security Policy (CSP) è un meccanismo di sicurezza implementato nei browser moderni che consente al server di specificare, tramite un HTTP header, quali origini sono autorizzate a fornire risorse (script, stili, immagini, font, frame) alla pagina corrente. È la principale difesa di seconda linea contro gli attacchi Cross-Site Scripting (XSS): anche se un attaccante riesce a iniettare codice nella pagina, il browser lo rifiuta se l’origine non è nella lista bianca.
CSP non elimina la necessità di sanificare l’input — rimane una misura di defense in depth.
Come funziona
Il server invia l’header:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.esempio.it; img-src *
Il browser analizza la policy e, per ogni risorsa che la pagina tenta di caricare, verifica se l’origine corrisponde alla direttiva applicabile. Se non corrisponde, la risorsa viene bloccata e l’evento viene registrato nella console (e opzionalmente inviato a un endpoint di reporting).
In alternativa all’header HTTP, CSP può essere dichiarata tramite un meta tag HTML, ma questa modalità ha limitazioni (non copre form-action, frame-ancestors, e altri).
Direttive principali
| Direttiva | Controlla |
|---|---|
default-src | Fallback per tutte le risorse non coperte da una direttiva specifica |
script-src | Script JavaScript |
style-src | Fogli di stile CSS |
img-src | Immagini |
font-src | Font |
connect-src | Richieste XHR, Fetch, WebSocket |
frame-src | Contenuto caricato in <iframe> |
frame-ancestors | Chi può incorporare questa pagina in un frame (difesa anti-clickjacking) |
form-action | A quali URL possono essere inviati i form |
base-uri | Valore dell’elemento <base> |
object-src | Plugin (<object>, <embed>, <applet>) |
upgrade-insecure-requests | Forza upgrade automatico da HTTP a HTTPS |
Valori delle sorgenti
'self' → stessa origine (schema + host + porta)
'none' → nessuna risorsa consentita
'unsafe-inline' → script/stili inline (sconsigliato: annulla protezione XSS)
'unsafe-eval' → eval() e funzioni dinamiche (sconsigliato)
https: → qualsiasi origine HTTPS
https://cdn.esempio.it → origine specifica
'nonce-<base64>' → script inline con nonce monouso
'sha256-<hash>' → script inline con hash SHA-256 specifico
Nonce e hash — la soluzione moderna
L’uso di 'unsafe-inline' svuota la protezione CSP perché consente qualsiasi script inline, inclusi quelli iniettati dall’attaccante. La soluzione corretta per gli script inline legittimi è:
Nonce: il server genera un valore casuale monouso per ogni risposta e lo include sia nella policy che nell’attributo nonce degli script legittimi:
<!-- Header -->
Content-Security-Policy: script-src 'nonce-r4nd0m1234'
<!-- HTML -->
<script nonce="r4nd0m1234">
// script legittimo
</script>
Un attaccante che inietta <script> senza conoscere il nonce viene bloccato.
Hash: alternativa al nonce per script con contenuto fisso — si include l’hash SHA-256 del testo dello script nella policy.
Modalità report-only
Durante il deployment, CSP può essere testata senza bloccare risorse usando l’header:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
Il browser invia un report JSON all’endpoint /csp-report per ogni violazione, ma non blocca nulla. Permette di affinare la policy prima di metterla in produzione.
Policy comune di partenza
Una policy ragionevole per la maggior parte delle applicazioni web:
Content-Security-Policy:
default-src 'none';
script-src 'self' 'nonce-{random}';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self';
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests;
default-src 'none' è il punto di partenza più restrittivo: tutto è vietato finché non esplicitamente consentito.
Errori comuni
'unsafe-inline'globale: neutralizza completamente la protezione XSS di CSP.'unsafe-eval': consenteeval(),setTimeout(string),new Function()— vettori di XSS.- Wildcard eccessivi:
script-src *equivale a nessun controllo. - Dimenticare
object-src 'none': i plugin legacy sono vettori di bypass. - CSP solo via meta tag: non copre
frame-ancestorsnéform-action. - Nonce statico: il nonce deve essere rigenerato a ogni risposta, non hardcoded.
Relazione con altri meccanismi
- Security Headers HTTP — CSP è uno degli header di sicurezza; la voce elenca l’intero set.
- Cross-Site Scripting (XSS) — la minaccia principale che CSP mitiga.
- Clickjacking —
frame-ancestorssostituisceX-Frame-Options. - HSTS — complementare a CSP per la sicurezza del trasporto.