Criteri di sicurezza del contenuto

Joe Medley
Joe Medley

Il modello di sicurezza del web è radicato nel criterio della stessa origine. Il codice di https://mybank.com deve avere accesso solo ai dati di https://mybank.com e l'accesso a https://evil.example.com non deve essere mai consentito. Ogni origine è isolata dal resto del web, offrendo agli sviluppatori una sandbox sicura in cui creare e giocare. In teoria, questo è perfettamente geniale. In pratica, gli aggressori hanno trovato modi intelligenti per sovvertire il sistema.

Gli attacchi cross-site scripting (XSS), ad esempio, aggirano la stessa norma di origine inducono con l'inganno un sito a distribuire codice dannoso insieme ai contenuti previsti. Questo è un enorme problema, perché i browser considerano tutto il codice visualizzato su una pagina come facente parte legittimamente dell'origine della sicurezza della pagina. La scheda di riferimento di XSS è una sezione trasversale vecchia ma rappresentativa dei metodi che un utente malintenzionato potrebbe utilizzare per violare questa fiducia iniettando codice dannoso. Se un utente malintenzionato inserisce con successo qualsiasi codice, si verifica praticamente il game over: i dati delle sessioni utente vengono compromessi e le informazioni che devono essere mantenute segrete vengono esfiltrate in The BadGuys. Ovviamente vorremmo evitare che ciò accada.

Questa panoramica evidenzia una difesa che può ridurre significativamente il rischio e l'impatto degli attacchi XSS nei browser moderni: Content Security Policy (CSP).

TL;DR

  • Utilizza le liste consentite per indicare al client cosa è consentito e cosa non lo è.
  • Scopri quali istruzioni sono disponibili.
  • Scopri le parole chiave che utilizzano.
  • Il codice in linea e eval() sono considerati dannosi.
  • Segnala le violazioni delle norme al server prima di applicarle.

Liste consentite di origine

Il problema sfruttato dagli attacchi XSS è l'incapacità del browser di distinguere tra lo script che fa parte della tua applicazione e lo script che è stato inserito per errore da una terza parte. Ad esempio, il pulsante +1 di Google nella parte inferiore di questa pagina carica ed esegue il codice da https://apis.google.com/js/plusone.js nel contesto dell'origine della pagina. Ci fidiamo di quel 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 non lo è. Il browser scarica ed esegue felicemente tutto il codice richiesto da una pagina, indipendentemente dal codice sorgente.

Invece di fidarsi ciecamente di tutto ciò che viene fornito da un server, CSP definisce l'intestazione HTTP Content-Security-Policy, che consente di creare una lista consentita di origini di contenuti attendibili e indica al browser di eseguire o visualizzare solo le risorse provenienti da queste origini. Anche se un utente malintenzionato riesce a trovare un buco attraverso il quale inserire lo script, lo script non corrisponderà alla lista consentita e quindi non verrà eseguito.

Poiché confidiamo nel fatto che apis.google.com fornisca codice valido e confidiamo nel fatto di 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 dello script valida e https://apis.google.com come altra. Il browser scarica ed esegue regolarmente JavaScript da apis.google.com tramite HTTPS e dall'origine della pagina corrente.

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

Con questo criterio definito, il browser genera semplicemente un errore invece di caricare lo script da qualsiasi altra origine. Quando un utente malintenzionato intelligente riesce a iniettare codice nel tuo sito, viene visualizzato a testa in giù in un messaggio di errore piuttosto che nel successo che si aspettava.

I criteri si applicano a un'ampia varietà di risorse

Sebbene le risorse degli script siano i rischi per la sicurezza più evidenti, CSP fornisce un ricco insieme di istruzioni relative ai criteri che consentono un controllo abbastanza granulare sulle risorse che è possibile caricare in una pagina. Hai già visto script-src, quindi il concetto dovrebbe essere chiaro.

Analizziamo rapidamente le altre istruzioni relative alle risorse. L'elenco seguente rappresenta lo stato delle istruzioni a partire dal livello 2. È stata pubblicata una specifica di livello 3, che però è in gran parte non implementata nei principali browser.

  • base-uri limita gli URL che possono essere visualizzati nell'elemento <base> di una pagina.
  • In child-src sono elencati gli URL dei worker e i contenuti del frame incorporato. Ad esempio, child-src https://youtube.com consente di incorporare video di YouTube, ma non di altre origini.
  • connect-src limita le origini a cui puoi connetterti (tramite XHR, WebSockets ed EventSource).
  • font-src specifica le origini che possono pubblicare caratteri web. I caratteri web di Google possono essere attivati tramite font-src https://themes.googleusercontent.com.
  • form-action elenca gli endpoint validi per l'invio dai tag <form>.
  • frame-ancestors specifica le fonti 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 deprecato nel livello 2, ma è stato ripristinato nel livello 3. Se non è presente, utilizza comunque child-src come prima.
  • img-src definisce le origini da cui è possibile caricare le immagini.
  • media-src limita le origini consentite per la pubblicazione di 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 le segnalazioni in caso di violazione di una norma sulla 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, passando da HTTP a HTTPS. Questa istruzione riguarda i siti web con un numero elevato di URL obsoleti che devono essere riscritti.
  • worker-src è un'istruzione CSP di livello 3 che limita gli URL che possono essere caricati come worker, worker condivisi o service worker. A partire da luglio 2017, questa istruzione ha implementazioni limitate.

Per impostazione predefinita, le istruzioni sono molto aperte. Se non imposti un criterio specifico per un'istruzione, ad esempio font-src, questa istruzione si comporta per impostazione predefinita anche se hai specificato * come origine valida (ad esempio, puoi caricare 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 direzioni non specificate. In genere, si applica a tutte le istruzioni che terminano con -src. Se il criterio default-src è impostato su https://example.com e non specifichi un'istruzione font-src, puoi caricare caratteri da https://example.com e da nessun'altra parte. 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 elemento di riserva. Ricorda che non farlo equivale a consentire qualsiasi cosa.

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

Puoi utilizzare tutte le istruzioni necessarie per la tua applicazione specifica, semplicemente elencandole nell'intestazione HTTP, separando le istruzioni con il punto e virgola. Assicurati di elencare tutte le risorse richieste di un tipo specifico in una singola istruzione. Se hai scritto qualcosa come script-src https://host1.com; script-src https://host2.com, la seconda istruzione verrebbe semplicemente ignorata. Qualcosa come il seguente specifica correttamente come valide entrambe le origini:

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 hai bisogno di plug-in o contenuti racchiusi in frame, il criterio potrebbe avere un aspetto simile al seguente:

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, dovresti ignorare queste intestazioni con prefisso. I browser moderni (ad eccezione di IE) supportano l'intestazione Content-Security-Policy senza prefisso. Questa è l'intestazione da utilizzare.

Indipendentemente dall'intestazione che utilizzi, le norme vengono definite pagina per pagina: devi inviare l'intestazione HTTP insieme a ogni risposta che vuoi assicurarti sia protetta. Ciò offre molta flessibilità, poiché puoi perfezionare le norme per pagine specifiche in base alle loro esigenze specifiche. È possibile che un insieme di pagine del tuo sito abbia un pulsante +1 e altre 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 un intervallo di specificità che va 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 solo 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 a example.com), 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 suoi sottodomini.
  • 'unsafe-inline' consente l'utilizzo di JavaScript e CSS incorporati. (Ne parleremo più in dettaglio tra poco.)
  • 'unsafe-eval' consente meccanismi di conversione da testo a JavaScript come eval. Ci occuperemo anche di questo.

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

Sandboxing

C'è un'altra istruzione di cui vale la pena di parlare: sandbox. È un po' diverso da tutti gli altri che abbiamo esaminato, in quanto pone restrizioni sulle azioni che la pagina può eseguire piuttosto che sulle risorse che la pagina può caricare. Se è presente l'istruzione sandbox, la pagina viene trattata come se fosse stata caricata all'interno di un <iframe> con un attributo sandbox. Ciò può avere un'ampia gamma di effetti sulla pagina, ad esempio forzare la pagina in un'origine unica e impedire l'invio di moduli. Non rientra nell'ambito di questo articolo, ma puoi trovare informazioni dettagliate sugli attributi di sandbox validi nella sezione"Sandbox" della specifica HTML5.

Il meta tag

Il meccanismo di consegna preferito dei CSP è un'intestazione HTTP. Tuttavia, può essere utile impostare un criterio su una pagina direttamente nel markup. Per farlo, 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'"
/>

Impossibile utilizzare questa opzione per frame-ancestors, report-uri o sandbox.

Il codice in linea è considerato dannoso

Dovrebbe essere chiaro che CSP si basa sulle origini della lista consentita, in quanto si tratta di un modo senza ambiguità di indicare al browser di considerare accettabili insiemi di risorse specifici e di rifiutare il resto. Le liste consentite basate sull'origine non risolvono la più grande minaccia rappresentata dagli attacchi XSS: inline script injection. 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 che lo consenta di distinguerlo da un tag di script in linea legittimo. CSP risolve il problema escludendo completamente lo script in linea: è l'unico modo per esserne sicuro.

Questa esclusione non comprende solo gli script incorporati direttamente nei tag script, ma anche i gestori di eventi in linea e gli URL javascript:. Dovrai spostare i contenuti dei tag script in un file esterno e sostituire gli URL di javascript: 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>

a qualcosa di più simile:

<!-- 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 offre una serie di vantaggi oltre a funzionare bene con CSP; è già una best practice, indipendentemente dall'uso di CSP. JavaScript incorporato mescola struttura e comportamento nel modo che non dovresti. Le risorse esterne sono più facili da memorizzare nella cache per i browser, più comprensibili per gli sviluppatori e favoriscono la compilazione e la minimizzazione. Scriverai un codice migliore se ti occupi di spostare il codice in risorse esterne.

Lo stile incorporato viene trattato nello stesso modo: sia l'attributo style sia i tag style devono essere consolidati in fogli di stile esterni per proteggersi da una serie di metodi di esfiltrazione dei dati stranamente intelligenti abilitati da CSS.

Se devi avere script e stile incorporati, puoi abilitarli aggiungendo 'unsafe-inline' come origine consentita in un'istruzione script-src o style-src. Puoi anche utilizzare un nonce o un hash (vedi sotto), ma in realtà non dovresti farlo. L'esclusione degli script in linea è la principale soluzione di sicurezza offerta da CSP e anche l'esclusione dello stile in linea rafforza l'applicazione. È necessario un po' di impegno in anticipo per assicurarsi che tutto funzioni correttamente dopo aver spostato tutto il codice fuori riga, ma è un compromesso che vale la pena fare.

Se devi assolutamente usarlo

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

Per utilizzare un nonce, assegna al tag script un attributo nonce. Il suo valore deve corrispondere a uno dell'elenco di 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 aggiunto 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 improbabili.

Gli hash funzionano più o meno allo stesso modo. 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 questo:

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

Le tue norme contengono quanto segue:

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

Qui ci sono alcuni aspetti importanti da tenere in considerazione. 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 necessari sia all'inizio che alla fine.

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

Anche Eval

Anche quando un utente malintenzionato non riesce a inserire direttamente lo script, potrebbe essere in grado di indurre con l'inganno la tua applicazione a convertire un testo altrimenti inerte in codice JavaScript eseguibile ed eseguirlo per suo conto. eval(), new Function(), setTimeout([string], ...) e setInterval([string], ...) sono tutti vettori attraverso i quali il testo iniettato potrebbe finire per eseguire qualcosa di inaspettatamente dannoso. La risposta predefinita di CSP a questo rischio è il blocco completo di tutti questi vettori.

Ciò influisce notevolmente sul modo in cui crei le applicazioni:

  • Devi analizzare il file 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 totalmente sicure.
  • Riscrivi le chiamate setTimeout o setInterval attualmente in corso con le funzioni in linea anziché con le stringhe. Ad esempio:
setTimeout("document.querySelector('a').style.display = 'none';", 10);

sarebbe scritto meglio come:

setTimeout(function () {
  document.querySelector('a').style.display = 'none';
}, 10);
  • Evita i 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'ottima applicazione di programmazione dinamica, ma rischia di valutare testo dannoso. Alcuni framework supportano immediatamente CSP, utilizzando un parser affidabile in assenza di eval. Un buon esempio è la direttiva ng-csp di AngularJS.

Tuttavia, una scelta migliore sarebbe un linguaggio di modelli che offra la precompilazione (ad esempio Handlebars). La precompilazione dei modelli può rendere l'esperienza utente ancora più veloce rispetto alla più rapida implementazione di runtime ed è anche più sicura. Se la valutazione e i relativi fratelli di testo in JavaScript sono essenziali per la tua applicazione, puoi abilitarli aggiungendo 'unsafe-eval' come origine consentita in un'istruzione script-src, ma sconsigliamo vivamente di farlo. Se vieti la possibilità di eseguire stringhe, per un utente malintenzionato è molto più difficile eseguire codice non autorizzato sul tuo sito.

Reporting

La capacità di CSP di bloccare le risorse non attendibili sul lato client è un vantaggio enorme per gli utenti, ma sarebbe molto utile inviare una notifica al server in modo da identificare e eliminare eventuali bug che consentono l'iniezione dannosa. A questo scopo, puoi indicare al browser di POST segnalare le violazioni nel formato JSON in una località specificata in un'istruzione report-uri.

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

Questi report avranno il seguente aspetto:

{
  "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 buona porzione di informazioni che ti aiuteranno a individuare la causa specifica della violazione, inclusa 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 ha violato il criterio della pagina (blocked-uri), la direttiva specifica violata (violated-directive) e la norma completa della pagina (original-policy).

Solo report

Se hai appena iniziato a utilizzare CSP, ha senso valutare lo stato attuale dell'applicazione prima di implementare un criterio draconiano per gli utenti. Come primo passo per il completamento del deployment, puoi chiedere al browser di monitorare un criterio, segnalando le violazioni ma senza applicare le restrizioni. 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à solo report non bloccherà le risorse limitate, ma invierà report sulle violazioni alla località specificata. Puoi anche inviare entrambe le intestazioni, applicando un criterio e monitorando un altro. Questo è un ottimo modo per valutare l'effetto delle modifiche al CSP della tua applicazione: attiva la segnalazione per un nuovo criterio, monitora le segnalazioni di violazioni e correggi eventuali bug riscontrati; quando il risultato ti soddisfa, inizia ad applicare il nuovo criterio.

Uso nel mondo reale

CSP 1 è abbastanza utilizzabile in Chrome, Safari e Firefox, ma ha un supporto molto limitato in IE 10. Puoi visualizzare le specifiche all'indirizzo caniuse.com. CSP di livello 2 è disponibile in Chrome dalla versione 40. L'intestazione è stata implementata da siti di grandi dimensioni come Twitter e Facebook (è utile leggere il case study di Twitter), che è già pronto per iniziare a eseguire il deployment sui tuoi siti.

Il primo passo per creare un criterio per la tua applicazione è valutare le risorse che stai effettivamente caricando. Quando pensi di avere una gestione su come vengono riuniti gli elementi nella tua app, configura un criterio basato su questi requisiti. Esaminiamo alcuni casi d'uso comuni e stabiliamo come potremmo essere in grado di supportarli entro i confini protettivi di CSP.

Caso d'uso 1: widget di social media

  • Il pulsante +1 di Google include uno script di https://apis.google.com e incorpora un elemento <iframe> da https://plusone.google.com. Devi avere un criterio che includa entrambe queste origini per incorporare il pulsante. Un criterio minimo sarebbe script-src https://apis.google.com; child-src https://plusone.google.com. Devi inoltre verificare che lo snippet di JavaScript fornito da Google venga estratto in un file JavaScript esterno. Se avevi un criterio basato su livello 1 che utilizzava frame-src Il livello 2 richiedeva di modificarlo in child-src. Questa operazione non è più necessaria in CSP di livello 3.

  • Il pulsante Mi piace di Facebook offre varie opzioni di implementazione. Ti consigliamo di continuare a utilizzare la versione di <iframe>, perché viene sottoposta in modo sicuro alla sandbox dal resto del sito. Richiede un'istruzione child-src https://facebook.com per funzionare correttamente. Tieni presente che, per impostazione predefinita, il codice <iframe> fornito da Facebook carica un URL relativo, //facebook.com. Modificalo 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. Anche Twitter fornisce un URL relativo per impostazione predefinita; modifica il codice per specificare HTTPS quando lo copi/incolli localmente. Il valore script-src https://platform.twitter.com; child-src https://platform.twitter.com sarà impostato, 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 consigliamo di impostare un default-src di 'none' e di guardare la console per determinare quali risorse dovrai abilitare per il funzionamento dei widget.

L'inclusione di più widget è molto semplice: basta combinare le direttive relative alle norme, ricordando di unire tutte le risorse di un singolo tipo in un'unica istruzione. Per tutti e tre i widget di social media, le norme avranno 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 2: blocco

Supponi per un momento di gestire un sito di banking e di voler assicurarti che possano essere caricate solo le risorse che hai scritto tu. In questo scenario, inizia con un criterio predefinito che blocchi assolutamente tutto (default-src 'none') e parti da lì.

Supponiamo che la banca carichi tutte le immagini, lo stile e lo script da una rete CDN su https://cdn.mybank.net e si connetta tramite XHR a https://api.mybank.com/ per recuperare 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, nienti extra. L'intestazione CSP più restrittiva che potremmo inviare è questa:

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 3: solo SSL

L'amministratore di un forum di discussione per le nozze vuole assicurarsi che tutte le risorse vengano caricate solo tramite canali sicuri, ma non scrive molto codice. Non può quindi riscrivere grandi parti del software del forum di terze parti riempite fino all'orlo di script e stile incorporati. Sarebbe efficace la seguente norma:

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

Anche se https: è specificato in default-src, lo script e le istruzioni di stile non ereditano automaticamente questa origine. Ogni istruzione sovrascrive completamente l'impostazione predefinita per quel tipo specifico di risorsa.

Il futuro

Il livello 2 del criterio di sicurezza del contenuto è un consiglio dei candidati. Il Web Application Security Working Group del W3C ha già iniziato a lavorare alla prossima iterazione della specifica, il livello 3 del criterio di sicurezza del contenuto.

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

Feedback