I contenuti attivi presenti sui siti web, come ad esempio Ja­va­Script, CSS e ActiveX, rap­pre­sen­ta­no un pericolo per gli utenti e per i gestori delle pagine web poiché potreste essere ma­ni­po­la­ti dai co­sid­det­ti Cross Site Scripting. Per fare sì che le pagine Internet possano essere uti­liz­za­te in modo esaustivo senza correre rischi, è stata in­tro­dot­ta la Content Security Policy (CSP). Questo standard di sicurezza, sup­por­ta­to dalla mag­gio­ran­za dei browser moderni, ha l’obiettivo di difendere i siti web dagli attacchi ci­ber­ne­ti­ci e, con­tem­po­ra­nea­men­te, di pro­teg­ge­re gli utenti. Ma cosa si nasconde dietro la CSP e come funziona?

Evo­lu­zio­ne della Content Security Policy

La Content Security Policy ha origini nel 2014 ed era ini­zial­men­te co­no­sciu­ta con il nome di “Content Re­stric­tion”. La nascita di questo progetto è stata provocata dalla quantità crescente di falle di sicurezza negli script di Internet; in par­ti­co­la­re il Cross Site Scripting (XSS), un metodo criminale per far entrare clan­de­sti­na­men­te dei malware in un de­ter­mi­na­to sito web, molto rischioso per gli utenti.

Può infatti accadere che si apra un sito Internet con­si­de­ra­to af­fi­da­bi­le, ma poi viene eseguito uno script che carica dati dannosi da una fonte sco­no­sciu­ta. I criminali in­for­ma­ti­ci possono uti­liz­za­re a questo scopo le falle di sicurezza presenti, ad esempio, nella funzione di in­se­ri­men­to commenti di un sito web. In questo modo i ma­lin­ten­zio­na­ti possono riuscire ad ottenere l’accesso al PC dell’utente senza che questo se ne accorga. Neanche i webmaster riescono a capire im­me­dia­ta­men­te quand’è che un codice esterno entra clan­de­sti­na­men­te in un sito Internet.

Per ovviare a questo problema, Mozilla Foun­da­tion ha deciso di ac­ce­le­ra­re lo sviluppo della CSP. Il vantaggio degli standard di sicurezza consiste nel fatto che è possibile stabilire quali script devono essere eseguiti dal software e quali no. Per fare questo la Content Security Policy ricorre agli header HTTP.

Fatto

Mozilla Foun­da­tion è l’or­ga­niz­za­zio­ne che si occupa dello sviluppo del browser di Firefox. Questa or­ga­niz­za­zio­ne no-profit gestisce il progetto di Mozilla e le in­no­va­zio­ni riguardo Internet. Mozilla Foun­da­tion è stata fondata dagli ex di­pen­den­ti di Netscape, che hanno svi­lup­pa­to il primo browser web.

Come funziona la Content Security Policy?

Durante la tra­smis­sio­ne di in­for­ma­zio­ni tramite Internet, tra i client e i server avviene uno scambio di dati mediante l’Hypertext Transfer Protocol (HTTP). Una delle com­po­nen­ti prin­ci­pa­li delle request e delle response sono gli header HTTP: questi campi vengono uti­liz­za­ti per tra­smet­te­re parametri e argomenti, im­por­tan­ti per lo scambio dei dati tra emittente e ricevente, ossia tra client e server. Sono ge­ne­ral­men­te suddivisi in campi di richiesta e risposta e, ad esempio, possono contenere in­for­ma­zio­ni sul set di caratteri, sulla lingua e sui cookie. La CSP viene im­ple­men­ta­ta in qualità di campo di in­te­sta­zio­ne della risposta. Ciò significa che il server fornisce le in­for­ma­zio­ni e il browser le elabora.

L’header della Content Security Policy viene im­ple­men­ta­to dal webmaster e inserito in tutte le sot­to­pa­gi­ne del sito web a cui si desidera applicare lo standard di sicurezza. Il gestore del sito Internet, inoltre, ha la pos­si­bi­li­tà di stabilire prov­ve­di­men­ti per la sicurezza che si dif­fe­ren­zia­no da pagina a pagina. È possibile im­ple­men­ta­re il concetto di sicurezza più fa­cil­men­te creando un file .htaccess nelle stesse cartelle (o in quelle ge­rar­chi­ca­men­te più alte) delle pagine web cor­ri­spon­den­ti o ancorando la CSP di­ret­ta­men­te nella con­fi­gu­ra­zio­ne del server.

N.B.

Se un utente vuole ve­ri­fi­ca­re se il proprio browser supporta o meno la Content Security Policy, è possibile eseguire il test per browser per CSP. Il test consiste nel provare ad eseguire alcuni script e a ri­chia­ma­re immagini da fonti sco­no­sciu­te (non dannose), mostrando all’utente se il pro­ce­di­men­to è andato a buon fine. Il browser in esame è sicuro se non ha caricato i dati delle fonti sco­no­sciu­te poiché ciò implica che capisce e utilizza la CSP.

In una Content Security Policy e al fine di prevenire lo scripting tra siti diversi, i webmaster do­vreb­be­ro me­mo­riz­za­re tutti gli script in file separati e non in­cor­po­rar­li di­ret­ta­men­te nel codice sorgente del proprio sito Internet. Questo indica che la CSP funziona secondo il principio della whitelist: nell’header vengono elencate le fonti da cui è possibile caricare gli script e i dati. Dunque, nel momento in cui viene inserito uno script sco­no­sciu­to nel codice HTML della pagina, il browser dell’utente deve proibire il ca­ri­ca­men­to di dati esterni. Per im­po­sta­zio­ne pre­de­fi­ni­ta, la CSP blocca tutti gli script inseriti di­ret­ta­men­te nel codice (inline scripting). Questo protegge sia il sito web che gli utenti, e so­prat­tut­to i loro dati sensibili.

Per i cy­ber­cri­mi­na­li le ma­ni­po­la­zio­ni tramite Cross Site Scripting sono re­la­ti­va­men­te semplici da attuare. Infatti quasi tutti i siti Internet sono dotati di un campo di input, come ad esempio la funzione di in­se­ri­men­to commenti, la barra di ricerca o il campo per ef­fet­tua­re il login: in queste sezioni, invece di inserire delle semplici parole, spesso vengono eseguiti degli script.

Dunque, se il server non è cor­ret­ta­men­te cautelato, i criminali in­for­ma­ti­ci possono im­ple­men­ta­re in­ter­fac­ce di phishing, causare un blocco del sito web oppure uti­liz­za­re dei malware per ottenere il controllo dell’utente tramite browser. La CSP (o più pre­ci­sa­men­te: l’header cor­ri­spet­ti­vo) comunica al browser web da quali fonti è con­sen­ti­to caricare dei dati. Se la policy è im­ple­men­ta­ta nel codice del sito web, al tentativo di re­cu­pe­ra­re quel codice in­tro­dot­to tramite XSS viene risposto con un messaggio di errore.

Tramite l’utilizzo della Content Security Policy i webmaster possono mo­di­fi­ca­re numerose im­po­sta­zio­ni, ad esempio, tramite le seguenti direttive:

  • base-uri: limita gli URL che possono comparire nell’elemento <base> della pagina web.
  • child-src: sta­bi­li­sce le fonti da cui trarre i dati che possono apparire nei frame, ad esempio i video forniti da terzi.
  • connect-src: limita le fonti alle quali il sito Internet può con­net­ter­si, ad esempio tramite link.
  • font-src: sta­bi­li­sce da quali fonti possono essere caricati i font
  • form-action: fornisce una lista di moduli endpoint validi.
  • frame-ancestors: sta­bi­li­sce quali domini possono strut­tu­ra­re la pagina in frame e iFrame.
  • img-src: sta­bi­li­sce da quali fonti possono essere caricate le immagini.
  • media-src: determina da quali fonti possono essere caricati formati audio e video.
  • object-src: controlla Flash e altri tipi di plug-in.
  • plugin-types: limita le tipologie di plug-in.
  • report-uri: specifica un URL a cui inviare i report in caso di vio­la­zio­ne delle misure di sicurezza.
  • script-src: determina quali fonti sono con­sen­ti­te per Ja­va­Script.
  • style-src: funziona come script-src, ma è usato per i fogli di stile.
  • upgrade-insecure-requests: sta­bi­li­sce che le pagine HTTP non protette vengano con­si­de­ra­te come pagine HTTPS.
  • sandbox: sposta la pagina in un sandbox in cui sono vietati moduli, pop-up e script.

Queste direttive sono valide solo se espli­ci­ta­men­te ri­co­no­sciu­te, al­tri­men­ti restano aperte di default, co­sti­tuen­do così una falla di sicurezza nel sistema. Tuttavia tramite il default-src è possibile eludere questo problema: con questo metodo si sta­bi­li­sco­no le im­po­sta­zio­ni di tutte le direttive che terminano con -src. Ad esempio, è possibile stabilire che il proprio sito Internet carichi soltanto i dati, a meno che non sia stato spe­ci­fi­ca­to di­ver­sa­men­te nel­l'hea­der HTTP di una singola pagina. Nelle direttive spe­ci­fi­che, inoltre, è possibile anche ag­giun­ge­re atre fonti.

Nell’header è possibile immettere un numero po­ten­zial­men­te infinito di direttive. Se si desidera includere più direttive, è ne­ces­sa­rio separarle con punto e virgola. Inoltre, il webmaster deve spe­ci­fi­ca­re tutte le sorgenti e le fonti all’interno di una direttiva. Non sono con­sen­ti­te citazioni multiple delle stesse direttive con fonti ag­giun­ti­ve. L’esempio seguente mostra un comando non ammesso:

script-src esempio1.local; script-src esempio2.local

In questo caso, solo la prima sorgente è rilevante, la seconda invece viene ignorata dal client. Al contrario, in una direttiva si devono spe­ci­fi­ca­re entrambe le sorgenti:

script-src esempio1.local esempio2.local

Se non si ha bisogno di de­ter­mi­na­ti tipi di contenuto per una pagina o per l'intero sito web, è possibile inserire il valore "none" nell’header cor­ri­spon­den­te, spe­ci­fi­can­do che non è possibile caricare alcuna fonte. È inoltre possibile uti­liz­za­re il valore "self" per spe­ci­fi­ca­re che il browser può caricare solo i contenuti pro­ve­nien­ti dalla stessa sorgente. Entrambi i valori devono sempre essere inclusi in vir­go­let­te singole, al­tri­men­ti "none" e "self" saranno in­ter­pre­ta­ti come domini.

Al fine di definire una Content Security Policy, nell’header possono essere inserite sintassi diverse:

  • Content-Security-Policy
  • X-Webkit-CSP
  • X-Content-Security-Policy

Non tutti i browser sup­por­ta­no tutte le de­no­mi­na­zio­ni. Tuttavia, il W3C (l’organismo che definisce gli standard per il web) propone una Content Security Policy uni­ver­sa­le. Pertanto tutti i browser più recenti si sono adattati a questo standard di sicurezza (le altre versioni sono con­si­de­ra­te obsolete). Per essere sicuri di rag­giun­ge­re il maggior numero possibile di utenti (anche quelli con versioni obsolete del browser) con la vostra CSP, è con­si­glia­bi­le im­ple­men­ta­re tutti gli header. Se un browser non è in grado di uti­liz­za­re l’header della Content Security Policy, lo ignora e vi­sua­liz­za il sito Internet fa­cil­men­te, ma senza offrire alcuna pro­te­zio­ne ag­giun­ti­va.

Di solito gli header HTTP vengono impostati su tutte le pagine del dominio. Per le sot­to­di­rec­to­ry è possibile uti­liz­za­re il file .htaccess. Suc­ces­si­va­men­te si utilizza lo standard di sicurezza CSP per definire regole speciali per le singole sot­to­pa­gi­ne. Ad esempio, se è stato im­ple­men­ta­to un pulsante per i social media in una pagina ma non in quella suc­ces­si­va, ha senso con­sen­ti­re l’accesso alla fonte esterna solo nel primo caso.

Le fonti possono essere immesse sia come indirizzi che come caratteri jolly. Sono pertanto con­sen­ti­ti i seguenti codici:

  • script-src "https://example.com:443" - Gli script sono con­sen­ti­ti solo da questo dominio tramite HTTPS.
  • script-src 'none'- Gli script non devono essere caricati.
  • script-src 'self' - Gli script possono essere caricati dalla stessa fonte della pagina corrente, ma non dai sot­to­do­mi­ni.
  • script-src https: - Gli script possono essere caricati da qualsiasi dominio a con­di­zio­ne che si utilizzi il pro­to­col­lo HTTPS.
  • script-src example.com - Gli script possono essere caricati da questo dominio.
  • script-src *.example.com - Gli script di questo dominio e di tutti i sot­to­do­mi­ni sono ammessi.
  • img-src data: - Le immagini possono essere caricate tramite lo schema data-URL.

In linea di massima una Content Security Policy sta­bi­li­sce che gli script possono essere caricati solo da file, non di­ret­ta­men­te dal codice del sito web. In al­ter­na­ti­va è possibile uti­liz­za­re lo script di comando script-src 'unsafe-inline', ma non si deve di­men­ti­ca­re che questo non assicura la completa sicurezza del sito. La norma di sicurezza vieta anche la funzione eval (). In realtà con questo comando è possibile con­ver­ti­re il testo in un codice Ja­va­Script, ma anche questo è un rischio per la sicurezza. Se avete ancora bisogno di questa funzione, potete riat­ti­var­la con script-src 'unsafe-eval'.

Consiglio

Tramite una piccola va­ria­zio­ne è possibile rendere più sicuro l’unsafe inline: uti­liz­zan­do gli hash oppure il Nonce-Source potrete colmare quasi to­tal­men­te le falle nel sistema di sicurezza.

Se non è più possibile vi­sua­liz­za­re gli script di­ret­ta­men­te nel codice, è ne­ces­sa­rio creare un file separato per ciascuno script. La funzione dello script è me­mo­riz­za­ta in un file .js. Solo questi sono men­zio­na­ti nel codice del sito web:

<script src='beispiel.js'></script>

Le azioni dello script sono descritte nel file example.js. È inoltre ne­ces­sa­rio me­mo­riz­za­re gli elementi di stile in fogli di stile separati. Se un webmaster vuole in­tro­dur­re una Internet Security Policy, non è suf­fi­cien­te im­ple­men­ta­re l’header. È inoltre ne­ces­sa­rio con­trol­la­re e adattare il codice sorgente del vostro sito web.

N.B.

Vuoi sapere quanto è sicuro il vostro sito web? Mozilla offre un test facile da usare: Ob­ser­va­to­ry by Mozilla vi darà un punteggio dopo una scansione e vi dirà in quali punti rendere il vostro sito web più sicuro.

Content Security Policy: un esempio

Di seguito vi il­lu­stria­mo come rea­liz­za­re una Content Security Policy, vi spie­ghia­mo come uti­liz­za­re l’header e quali risultati potete rag­giun­ge­re.

  • Content-Security-Policy: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' https://fonts.google.com/; report-uri 'https://example.org/report.html';
  • X-Content-Security-Policy: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' https://fonts.google.com/; report-uri 'https://example.org/report.html';
  • X-WebKit-CSP: "default-src 'none'; script-src 'self' *.example.com; style-src 'self'; img-src 'self' data:; font-src 'self' https://fonts.google.com/; report-uri 'https://example.org';

Dall’esempio di cui sopra si può evincere che ogni variante di CSP compare nell’header in modo da poter ri­chia­ma­re quanti più browser possibili. Ogni nome dell’header riporta lo stesso contenuto: le fonti sono elencate una dopo l’altra e le direttive sono separate da un punto e virgola. La sintassi è quindi sempre la stessa. Infatti cambia solo il nome del campo, in modo da poterne sem­pli­ce­men­te duplicare il contenuto.

In primo luogo bisogna spe­ci­fi­ca­re che, salvo altre in­di­ca­zio­ni riportate in una direttiva, i dati non devono essere caricati da alcuna fonte (default-src). Operando in questo modo è possibile colmare falle nella sicurezza. Per questo motivo il default-src deve essere sempre spe­ci­fi­ca­to per primo. Questo evita che qualsiasi altra direttiva non spe­ci­fi­ca­ta possa causare problemi nella vostra Content Security Policy.

Nel prossimo passaggio bisogna definire le fonti da cui possono essere caricati gli script (script-src). Nell’esempio abbiamo spe­ci­fi­ca­to che il browser esegue solo gli script pro­ve­nien­ti dalla stessa sorgente e da example.com, inclusi tutti i suoi sot­to­do­mi­ni (la wildcard viene assegnata tramite *). Inoltre i client possono caricare i fogli di stile solo dalla propria sorgente (style-src). Anche il ca­ri­ca­men­to delle immagini è con­sen­ti­to solo se ef­fet­tua­to dalla stessa fonte e come schema data-URL (img-src). A seconda dell’header della Content Security Policy, i font possono essere caricati solo dalla sorgente. Infine, nel­l'e­sem­pio, viene spe­ci­fi­ca­to un indirizzo a cui inviare i messaggi, nel caso si ve­ri­fi­cas­se un tentativo di vio­la­zio­ne dello standard di sicurezza (report-uri).

Noterete che nell’header non sono state im­ple­men­ta­te tutte le direttive, ma non è un fattore de­ter­mi­nan­te: nel caso spe­ci­fi­ca­to poco sopra non si necessita di altre whitelist; e tramite il default-src le altre sorgenti vengono di­sat­ti­va­te.

Consiglio

Su Internet sono di­spo­ni­bi­li diversi ge­ne­ra­to­ri di Content Security Policy. Con offerte come CSP Is Awesome oppure Report URI è possibile creare un header per CSP in modo semplice e af­fi­da­bi­le.

Vai al menu prin­ci­pa­le