Criteri di sicurezza del contenuto

Mike West
Joe Medley
Mario Bianchi

Il modello di sicurezza del web è rooted nel criterio della stessa origine. Il codice proveniente da https://mybank.com dovrebbe avere accesso soltanto ai dati di https://mybank.com e certamente a https://evil.example.com non dovrebbe mai essere consentito l'accesso. Ogni origine è isolata dal resto del web, offrendo agli sviluppatori una sandbox sicura in cui creare e giocare. In teoria, è tutto geniale. In pratica, degli autori di attacchi hanno trovato dei modi intelligenti per sovvertire il sistema.

Gli attacchi cross-site scripting (XSS), ad esempio, ignorano gli stessi criteri di origine inducendo con l'inganno un sito a inviare codice dannoso insieme ai contenuti previsti. Questo è un enorme problema, in quanto i browser considerano attendibile tutto il codice visualizzato in una pagina che fa parte legittimamente dell'origine di sicurezza di tale pagina. La scheda di riferimento XSS è una vecchia ma rappresentativa cross-sezione dei metodi che un utente malintenzionato potrebbe utilizzare per violare questa fiducia inserendo codice dannoso. Se un utente malintenzionato inserisce correttamente qualsiasi codice, il gioco è quasi finito: i dati delle sessioni utente vengono compromessi e le informazioni che devono essere tenute segrete vengono esfiltrate in The Bad Guys. Vorremmo ovviamente impedire che ciò si verifichi, se possibile.

Questa panoramica evidenzia una difesa in grado di ridurre in modo significativo il rischio e l'impatto di attacchi XSS nei browser moderni: il criterio di sicurezza del contenuto (CSP).

TL;DR

  • Utilizza le liste consentite per comunicare al cliente cosa è consentito e cosa non lo è.
  • Scopri quali istruzioni sono disponibili.
  • Imparare a conoscere le parole chiave che utilizzano.
  • Il codice incorporato e eval() sono considerati dannosi.
  • Segnala al tuo server le violazioni delle norme prima di applicarle.

Liste consentite di origini

Il problema sfruttato dagli attacchi XSS è l'incapacità del browser di distinguere tra lo script che fa parte dell'applicazione e lo script inserito in modo malevolo da una terza parte. Ad esempio, il pulsante +1 di Google nella parte inferiore di questa pagina carica ed esegue codice da https://apis.google.com/js/plusone.js nel contesto dell'origine della pagina. Ci fidiamo di questo codice, ma non possiamo aspettarci che il browser capisca da solo che il codice di apis.google.com è fantastico, mentre il codice di apis.evil.example.com probabilmente no. Il browser scarica ed esegue volentieri qualsiasi codice richiesto da una pagina, indipendentemente dall'origine.

Invece di fidarsi ciecamente di tutto un server, CSP definisce l'intestazione HTTP Content-Security-Policy, che consente di creare una lista consentita di fonti di contenuti attendibili e indica al browser di eseguire o visualizzare le risorse provenienti solo da quelle origini. Anche se un utente malintenzionato riesce a trovare un punto libero da cui inserire lo script, quest'ultimo non corrisponderà alla lista consentita e pertanto non verrà eseguito.

Poiché confidiamo nel fatto che apis.google.com fornisca codice valido e confidiamo di poter fare lo stesso, definiamo un criterio che consenta l'esecuzione dello script solo quando proviene da una di queste due origini:

Content-Security-Policy: script-src 'self' https://apis.google.com

Semplice, vero? Come avrai intuito, script-src è un'istruzione che controlla un insieme di privilegi relativi agli script per una pagina specifica. Abbiamo specificato 'self' come origine valida dello script e https://apis.google.com come un'altra. Il browser scarica ed esegue regolarmente JavaScript da apis.google.com tramite HTTPS, nonché dall'origine della pagina corrente.

Errore della console: è stato rifiutato il caricamento dello script "http://evil.example.com/evil.js" perché viola la seguente istruzione relativa ai criteri di sicurezza del contenuto: script-src "self" https://apis.google.com

Una volta definito questo criterio, il browser genera semplicemente un errore anziché caricare script da qualsiasi altra origine. Quando un utente malintenzionato intelligente riesce a inserire codice nel tuo sito, viene visualizzato un messaggio di errore piuttosto che i risultati sperati.

Le norme si applicano a un'ampia varietà di risorse

Sebbene le risorse di script siano i rischi per la sicurezza più evidenti, CSP fornisce un'ampia gamma di direttive di criteri che consentono un controllo abbastanza granulare sulle risorse che una pagina è autorizzata a caricare. Hai già visto script-src, quindi il concetto dovrebbe essere chiaro.

Esaminiamo rapidamente le altre istruzioni sulle risorse. L'elenco che segue rappresenta lo stato delle direttive a partire dal livello 2. È stata pubblicata una specifica di livello 3, ma in gran parte non implementata nei browser principali.

  • base-uri limita gli URL che possono essere visualizzati nell'elemento <base> di una pagina.
  • child-src elenca gli URL per i worker e i contenuti dei frame incorporati. Ad esempio: child-src https://youtube.com consentirebbe l'incorporamento di video da YouTube, ma non da altre origini.
  • connect-src limita le origini a cui puoi connetterti (tramite XHR, WebSockets ed EventSource).
  • font-src specifica le origini che possono fornire caratteri web. I caratteri web di Google possono essere attivati tramite font-src https://themes.googleusercontent.com.
  • form-action elenca endpoint validi per l'invio dai tag <form>.
  • frame-ancestors specifica le origini che possono incorporare la pagina corrente. Questa istruzione si applica ai tag <frame>, <iframe>, <embed> e <applet>. Questa istruzione non può essere utilizzata nei tag <meta> e si applica solo alle risorse non HTML.
  • frame-src è stato ritirato nel livello 2, ma ripristinato nel livello 3. In caso contrario, torna a child-src come prima.
  • img-src definisce le origini da cui è possibile caricare le immagini.
  • media-src limita le origini autorizzate a pubblicare video e audio.
  • object-src consente di controllare Flash e altri plug-in.
  • plugin-types limita i tipi di plug-in che una pagina può richiamare.
  • report-uri specifica un URL a cui un browser invia segnalazioni in caso di violazione di un criterio di sicurezza dei contenuti. Questa istruzione non può essere utilizzata nei tag <meta>.
  • style-src è la controparte di script-src per i fogli di stile.
  • upgrade-insecure-requests indica agli user agent di riscrivere gli schemi URL, cambiando HTTP in HTTPS. Questa istruzione è destinata ai siti web con un numero elevato di URL precedenti che devono essere riscritti.
  • worker-src è un'istruzione CSP di livello 3 che limita gli URL che possono essere caricati come worker, shared worker o service worker. A partire da luglio 2017, questa istruzione ha implementazioni limitate.

Per impostazione predefinita, le istruzioni sono aperte. Se non imposti un criterio specifico per un'istruzione, ad esempio font-src, l'istruzione si comporta per impostazione predefinita come se avessi specificato * come origine valida (ad esempio, potresti caricare i caratteri da qualsiasi luogo, senza limitazioni).

Puoi ignorare questo comportamento predefinito specificando un'istruzione default-src. Questa istruzione definisce i valori predefiniti per la maggior parte delle istruzioni che non specifichi. In genere, si applica a qualsiasi istruzione che termina con -src. Se default-src è impostato su https://example.com e non riesci a specificare un'istruzione font-src, puoi caricare i caratteri da https://example.com e non da nessun altro. Nei nostri esempi precedenti abbiamo specificato solo script-src, il che significa che le immagini, i caratteri e così via possono essere caricati da qualsiasi origine.

Le seguenti istruzioni non utilizzano default-src come riserva. Ricorda che se non li imposti, equivale a consentire qualsiasi cosa.

  • base-uri
  • form-action
  • frame-ancestors
  • plugin-types
  • report-uri
  • sandbox

Puoi utilizzare il numero di istruzioni che ritieni opportuno per la tua applicazione specifica, semplicemente elencandole nell'intestazione HTTP e separandole con un punto e virgola. Assicurati di elencare tutte le risorse di un tipo specifico richieste in una singola istruzione. Se scrivi qualcosa come script-src https://host1.com; script-src https://host2.com, la seconda istruzione viene semplicemente ignorata. Qualcosa di seguito indicherebbe correttamente entrambe le origini come valide:

script-src https://host1.com https://host2.com

Se, ad esempio, hai un'applicazione che carica tutte le sue risorse da una rete CDN (Content Delivery Network) (ad esempio https://cdn.example.net) e sai che non ti servono plug-in o contenuti racchiusi in frame, le norme potrebbero avere il seguente aspetto:

Content-Security-Policy: default-src https://cdn.example.net; child-src 'none'; object-src 'none'

Dettagli di implementazione

Vedrai le intestazioni X-WebKit-CSP e X-Content-Security-Policy in vari tutorial sul Web. D'ora in poi, dovrai ignorare queste intestazioni prefissate. I browser moderni (con l'eccezione di IE) supportano l'intestazione Content-Security-Policy senza prefisso. Questa è l'intestazione da utilizzare.

Indipendentemente dall'intestazione utilizzata, il criterio viene definito pagina per pagina: devi inviare l'intestazione HTTP insieme a ogni risposta che vuoi garantire che sia protetta. Ciò offre molta flessibilità, in quanto è possibile perfezionare i criteri per pagine specifiche in base alle loro esigenze specifiche. Forse un insieme di pagine del tuo sito ha un pulsante +1, mentre altri no: puoi consentire il caricamento del codice del pulsante solo quando necessario.

L'elenco delle origini in ogni istruzione è flessibile. Puoi specificare le origini in base allo schema (data:, https:) o in base alla specificità, da solo nome host (example.com, che corrisponde a qualsiasi origine su quell'host: qualsiasi schema, qualsiasi porta) a un URI completo (https://example.com:443, che corrisponde solo a HTTPS, solo a example.com e alla porta 443). I caratteri jolly sono accettati, ma solo come schema, porta o nella posizione più a sinistra del nome host: *://*.example.com:* corrisponde a tutti i sottodomini di example.com (ma non example.com stesso), utilizzando qualsiasi schema, su qualsiasi porta.

L'elenco di origine accetta anche quattro parole chiave:

  • 'none', come previsto, non corrisponde a nulla.
  • 'self' corrisponde all'origine attuale, ma non ai relativi sottodomini.
  • 'unsafe-inline' consente JavaScript e CSS incorporati. (Approfondiremo questo aspetto più in dettaglio.)
  • 'unsafe-eval' consente meccanismi da testo a JavaScript come eval. (Approfondiremo anche questo).

Queste parole chiave richiedono virgolette singole. Ad esempio, script-src 'self' (con le virgolette) autorizza l'esecuzione di JavaScript dall'host corrente; script-src self (senza virgolette) consente JavaScript da un server denominato "self" (e non dall'host corrente), il che probabilmente non è quello che intendevi.

Sandboxing

C'è un'altra istruzione di cui vale la pena parlare: sandbox. È un po' diverso dalle altre che abbiamo visto, poiché pone restrizioni sulle azioni che la pagina può eseguire piuttosto che sulle risorse che può caricare. Se è presente l'istruzione sandbox, la pagina viene trattata come se fosse stata caricata all'interno di un elemento <iframe> con un attributo sandbox. Questo può avere una vasta gamma di effetti sulla pagina, tra cui forzare la pagina in un'origine univoca e impedire l'invio di moduli. Questo articolo va un po' oltre l'ambito di questo articolo, ma puoi trovare informazioni dettagliate sugli attributi di sandboxing validi nella sezione "Sandboxing" delle specifiche HTML5.

Il meta tag

Il meccanismo di pubblicazione preferito dei CSP è un'intestazione HTTP. Tuttavia, può essere utile impostare un criterio per una pagina direttamente nel markup. A tal fine, utilizza un tag <meta> con un attributo http-equiv:

<meta
  http-equiv="Content-Security-Policy"
  content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'"
/>

Non può essere utilizzata per frame-ancestors, report-uri o sandbox.

Il codice incorporato è considerato dannoso

Dovrebbe essere chiaro che il CSP si basa sulle origini della lista consentita, in quanto si tratta di un modo inequivocabile per indicare al browser di trattare insiemi specifici di risorse come accettabili e di rifiutare il resto. Tuttavia, le liste consentite basate sull'origine non sono in grado di risolvere la più grande minaccia rappresentata dagli attacchi XSS: l'iniezione di script in linea. Se un utente malintenzionato può inserire un tag di script che contiene direttamente un payload dannoso (<script>sendMyDataToEvilDotCom();</script>), il browser non ha alcun meccanismo per distinguerlo da un tag di script in linea legittimo. CSP risolve questo problema escludendo completamente lo script incorporato: è l'unico modo per averne la certezza.

Questa esclusione include non solo gli script incorporati direttamente nei tag script, ma anche gestori di eventi incorporati e URL javascript:. Dovrai spostare i contenuti dei tag script in un file esterno e sostituire javascript: URL e <a ... onclick="[JAVASCRIPT]"> con le chiamate addEventListener() appropriate. Ad esempio, potresti riscrivere quanto segue da:

<script>
  function doAmazingThings() {
    alert('YOU AM AMAZING!');
  }
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>

ad esempio:

<!-- amazing.html -->
<script src="amazing.js"></script>
<button id="amazing">Am I amazing?</button>

<div style="clear:both;"></div>
// amazing.js
function doAmazingThings() {
  alert('YOU AM AMAZING!');
}
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('amazing').addEventListener('click', doAmazingThings);
});

Il codice riscritto presenta una serie di vantaggi che vanno oltre il buon funzionamento con il CSP: si tratta già di una best practice, a prescindere dall'uso che fai di CSP. JavaScript incorporato combina struttura e comportamento in modo esatto. Le risorse esterne sono più facili da memorizzare nella cache per i browser, sono più comprensibili per gli sviluppatori e favoriscono la compilazione e la minimizzazione. Magari scriverai un codice migliore se ti occuperai di spostare il codice in risorse esterne.

Lo stile incorporato viene gestito allo stesso modo: sia l'attributo style che i tag style devono essere consolidati in fogli di stile esterni per proteggerti da una serie di metodi di esfiltrazione dei dati sorprendentemente intelligenti consentiti da CSS.

Se devi disporre di script e stile incorporati, puoi abilitarli aggiungendo 'unsafe-inline' come origine consentita in un'istruzione script-src o style-src. Puoi anche usare un nonce o un hash (vedi sotto), ma in realtà non dovresti. L'esclusione dello script incorporato è la soluzione più efficace per la sicurezza offerta da CSP, mentre l'esclusione dello stile incorporato rende più sicura la tua applicazione. Occorre un po' di impegno iniziale per assicurarsi che tutto funzioni correttamente dopo aver spostato tutto il codice fuori riga, ma si tratta di un compromesso che vale la pena fare.

Se assolutamente devi utilizzarla

CSP livello 2 offre compatibilità con le versioni precedenti per gli script incorporati, consentendoti di aggiungere script incorporati specifici alla lista consentita utilizzando un nonce crittografico (numero utilizzato una volta) o un hash. Anche se può sembrare ingombrante, è utile in caso di necessità.

Per utilizzare un nonce, assegna al tag script un attributo nonce. e deve corrispondere a uno dell'elenco delle origini attendibili. Ad esempio:

<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
  // Some inline code I can't remove yet, but need to asap.
</script>

Ora aggiungi il nonce all'istruzione script-src aggiunta alla parola chiave nonce-.

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

Ricorda che i nonce devono essere rigenerati per ogni richiesta di pagina e devono essere non decifrabili.

Gli hash funzionano in modo analogo. Anziché aggiungere codice al tag script, crea un hash SHA dello script stesso e aggiungilo all'istruzione script-src. Ad esempio, supponiamo che la tua pagina contenga quanto segue:

<script>
  alert('Hello, world.');
</script>

La tua norma conterrebbe quanto segue:

Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

Occorre tenere presente alcuni aspetti. Il prefisso sha*- specifica l'algoritmo che genera l'hash. Nell'esempio precedente, viene utilizzato sha256-. CSP supporta anche sha384- e sha512-. Quando generi l'hash, non includere i tag <script>. Anche le lettere maiuscole e gli spazi vuoti sono importanti, inclusi gli spazi vuoti iniziali o finali.

Una ricerca su Google sulla generazione di hash SHA ti porterà a soluzioni in diverse lingue. Con Chrome 40 o versioni successive, puoi aprire DevTools e ricaricare la pagina. La scheda Console conterrà i messaggi di errore con l'hash sha256 corretto per ciascuno dei tuoi script incorporati.

Valuta anche

Anche se un utente malintenzionato non può inserire direttamente lo script, potrebbe essere in grado di indurre con l'inganno l'applicazione a convertire un testo altrimenti inerte in codice JavaScript eseguibile ed eseguirlo per suo conto. eval(), le nuove funzioni Functions(), setTimeout([string], ...) e setInterval([string], ...) sono tutti vettori attraverso i quali il testo inserito potrebbe finire per eseguire qualcosa di inaspettatamente dannoso. La risposta predefinita del CSP a questo rischio è bloccare completamente tutti questi vettori.

Questo ha più di qualche impatto sul modo in cui crei le applicazioni:

  • Devi analizzare JSON tramite la JSON.parse integrata, anziché utilizzare eval. Le operazioni JSON native sono disponibili in tutti i browser a partire da IE8 e sono completamente sicure.
  • Riscrivi le chiamate setTimeout o setInterval che stai effettuando attualmente con funzioni incorporate anziché stringhe. Ad esempio:
setTimeout("document.querySelector('a').style.display = 'none';", 10);

si scriverebbe meglio:

setTimeout(function () {
  document.querySelector('a').style.display = 'none';
}, 10);
  • Evita la creazione di modelli incorporati in fase di runtime: molte librerie di modelli utilizzano liberamente new Function() per velocizzare la generazione dei modelli in fase di runtime. È un'elegante applicazione della programmazione dinamica, ma rischia di valutare il testo dannoso. Alcuni framework supportano CSP da subito, utilizzando un parser solido in assenza di eval. L'istruzione ng-csp di AngularJS ne è un buon esempio.

Tuttavia, una scelta migliore sarebbe un linguaggio basato su modelli che offre la precompilazione (ad esempio Handlebars). La precompilazione dei modelli può rendere l'esperienza utente ancora più veloce rispetto all'implementazione di runtime più veloce, oltre a essere più sicura. Se eval e i relativi fratelli da testo a JavaScript sono essenziali per la tua applicazione, puoi abilitarli aggiungendo 'unsafe-eval' come sorgente consentita in un'istruzione script-src, ma sconsigliamo vivamente di farlo. Escludendo la capacità di eseguire stringhe, è molto più difficile per un utente malintenzionato eseguire codice non autorizzato sul vostro sito.

Report

La capacità di CSP di bloccare risorse non attendibili sul lato client è un'ottima vittoria per gli utenti, ma sarebbe molto utile inviare al server una qualche tipo di notifica in modo da poter identificare e eliminare eventuali bug che consentono l'inserimento dannoso prima di tutto. A questo scopo, puoi indicare al browser di POST segnalare le violazioni in formato JSON in una posizione specificata in un'istruzione report-uri.

Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

Questi report si presenteranno in modo simile al seguente:

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}

Contiene una serie di informazioni utili che ti aiuteranno a rintracciare la causa specifica della violazione, tra cui la pagina in cui si è verificata la violazione (document-uri), il referrer della pagina (tieni presente che, a differenza del campo dell'intestazione HTTP, la chiave non contiene errori di ortografia), la risorsa che viola le norme della pagina (blocked-uri), l'istruzione specifica violata (violated-directive) e le norme complete della pagina (original-policy).

Solo report

Se hai appena iniziato a utilizzare CSP, ti consigliamo di valutare lo stato attuale della tua applicazione prima di implementare un criterio draconiano per gli utenti. Come passaggio per un deployment completo, puoi chiedere al browser di monitorare un criterio, segnalare le violazioni ma non applicarle. Anziché inviare un'intestazione Content-Security-Policy, invia un'intestazione Content-Security-Policy-Report-Only.

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

Il criterio specificato in modalità di sola segnalazione non bloccherà le risorse limitate, ma invierà le segnalazioni di violazione alla località specificata. Puoi anche inviare entrambe le intestazioni, applicando un criterio e monitorandone un altro. Questo è un ottimo modo per valutare l'effetto delle modifiche al CSP dell'applicazione: attivare la segnalazione di un nuovo criterio, monitorare le segnalazioni di violazioni e correggere eventuali bug; una volta soddisfatti gli effetti, inizia ad applicare le nuove norme.

Utilizzo reale

CSP 1 è abbastanza utilizzabile in Chrome, Safari e Firefox, ma ha un supporto molto limitato in IE 10. Puoi consultare le specifiche su caniuse.com. CSP Livello 2 è disponibile in Chrome sin dalla versione 40. Siti di grandi dimensioni come Twitter e Facebook hanno implementato l'intestazione (meglio leggere il case study di Twitter) e lo standard è già pronto per consentirti di iniziare a implementarlo sui tuoi siti.

Il primo passaggio nella creazione di un criterio per la tua applicazione consiste nel valutare le risorse che stai effettivamente caricando. Una volta che pensi di avere un controllo su come sono organizzati gli elementi nella tua app, configura un criterio basato su quei requisiti. Esaminiamo alcuni casi d'uso comuni e cerchiamo di determinare come potremmo supportarli al meglio entro i confini protettivi di CSP.

Caso d'uso n. 1: widget di social media

  • Il pulsante +1 di Google include uno script di https://apis.google.com e incorpora un <iframe> di https://plusone.google.com. Per incorporare il pulsante, è necessaria una norma che includa entrambe le origini. Un criterio minimo sarebbe script-src https://apis.google.com; child-src https://plusone.google.com. Devi inoltre assicurarti che lo snippet di codice JavaScript fornito da Google venga estratto in un file JavaScript esterno. Se avevi un criterio basato sul Livello 1 che utilizzava frame-src, il Livello 2 richiedeva di cambiarlo in child-src. Questo non è più necessario in CSP di livello 3.

  • Il pulsante Mi piace di Facebook offre varie opzioni di implementazione. Ti consigliamo di continuare a utilizzare la versione <iframe>, che viene limitata in modo sicuro tramite sandbox dal resto del tuo sito. Per funzionare correttamente, richiede un'istruzione child-src https://facebook.com. Tieni presente che, per impostazione predefinita, il codice <iframe> fornito da Facebook carica un URL relativo, ovvero //facebook.com. Modifica questa impostazione per specificare esplicitamente HTTPS: https://facebook.com. Non c'è motivo di utilizzare HTTP se non è necessario.

  • Il pulsante Tweet di Twitter si basa sull'accesso a uno script e a un frame, entrambi ospitati su https://platform.twitter.com. Allo stesso modo, Twitter fornisce un URL relativo per impostazione predefinita; modifica il codice in modo da specificare HTTPS quando lo copi e lo incolli localmente. È tutto impostato su script-src https://platform.twitter.com; child-src https://platform.twitter.com, a patto che sposti lo snippet JavaScript fornito da Twitter in un file JavaScript esterno.

  • Altre piattaforme hanno requisiti simili e possono essere affrontati in modo simile. Ti suggeriamo di impostare un default-src pari a 'none' e di controllare la tua console per determinare quali risorse dovrai attivare per far funzionare i widget.

Includere più widget è semplice: è sufficiente combinare le istruzioni relative alle norme, ricordando di unire tutte le risorse di un singolo tipo in un'unica direttiva. Se volessi utilizzare tutti e tre i widget di social media, la norma avrebbe il seguente aspetto:

script-src https://apis.google.com https://platform.twitter.com; child-src https://plusone.google.com https://facebook.com https://platform.twitter.com

Caso d'uso n. 2: blocco

Supponiamo che tu gestisca un sito di online banking e voglia assicurarti che possano essere caricate solo le risorse che hai scritto. In questo scenario, inizia con un criterio predefinito che blocchi assolutamente tutto (default-src 'none') e continua a creare da qui.

Supponiamo che la banca carichi tutte le immagini, lo stile e lo script da una CDN a https://cdn.mybank.net e si connetta tramite XHR a https://api.mybank.com/ per estrarre vari bit di dati. Vengono utilizzati i frame, ma solo per le pagine locali del sito (senza origini di terze parti). Non c'è Flash sul sito, né caratteri, né extra. L'intestazione CSP più restrittiva che possiamo inviare è la seguente:

Content-Security-Policy: default-src 'none'; script-src https://cdn.mybank.net; style-src https://cdn.mybank.net; img-src https://cdn.mybank.net; connect-src https://api.mybank.com; child-src 'self'

Caso d'uso n. 3: solo SSL

L'amministratore di un forum di discussione di matrimoni vuole assicurarsi che tutte le risorse vengano caricate solo tramite canali sicuri, ma in realtà non scriva molto codice; riscrivere grandi blocchi di software per forum di terze parti pieni di script e stile incorporati va al di là delle sue capacità. La seguente norma sarebbe efficace:

Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'

Anche se https: è specificato in default-src, le istruzioni relative a script e stile non ereditano automaticamente questa origine. Ogni istruzione sovrascrive completamente il valore predefinito per quel tipo specifico di risorsa.

Il futuro

Il livello 2 dei criteri di sicurezza del contenuto è un suggerimento per i candidati. Il Web Application Security Working Group del W3C ha già iniziato a lavorare alla prossima iterazione della specifica, Content Security Policy Level 3.

Se ti interessa la discussione su queste funzionalità in arrivo, scorri gli archivi delle mailing list pubbliche-webappsec@ o partecipa anche tu.

Feedback