Il modello di sicurezza del web si basa sul
criterio della stessa origine. Il codice di https://mybank.com
deve avere accesso solo ai dati di https://mybank.com
e non deve mai essere consentito l'accesso a https://evil.example.com
.
Ogni origine viene mantenuta isolata dal resto del web, offrendo agli sviluppatori un ambiente sicuro in cui creare e giocare. In teoria, è un'idea perfetta. In pratica, gli aggressori hanno trovato modi intelligenti per aggirare il sistema.
Ad esempio, gli attacchi di cross-site scripting (XSS) aggirano il criterio della stessa origine ingannando un sito affinché invii codice dannoso insieme ai contenuti previsti. Si tratta di un problema enorme, poiché i browser ritengono attendibile tutto il codice visualizzato in una pagina come parte legittima dell'origine della sicurezza della pagina. La cheat sheet XSS è una vecchia, ma rappresentativa, sezione trasversale dei metodi che un malintenzionato potrebbe utilizzare per violare questa attendibilità 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 cliente cosa è consentito e cosa no.
- Scopri quali direttive sono disponibili.
- Scopri le parole chiave che utilizzano.
- Il codice in linea e
eval()
sono considerati dannosi. - Segnala le violazioni delle norme al tuo 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 quello che è stato inserito deliberatamente da una terza parte. Ad esempio, il pulsante Google +1 nella parte inferiore di questa pagina carica ed esegue il codice di https://apis.google.com/js/plusone.js
nel contesto dell'origine di questa 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 qualsiasi codice richiesto da una pagina, indipendentemente dalla sorgente.
Invece di fidarsi ciecamente di tutto ciò che viene pubblicato da un server, i CSP definiscono l'intestazione HTTP Content-Security-Policy
, che consente di creare una lista consentita di sorgenti di contenuti attendibili e indica al browser di eseguire o visualizzare solo risorse provenienti da quelle sorgenti. 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 probabilmente hai intuito, script-src
è una direttiva che controlla un insieme di privilegi relativi agli script per una pagina specifica. Abbiamo specificato
'self'
come una fonte valida di script e https://apis.google.com
come
un'altra. Il browser scarica ed esegue diligentemente il codice JavaScript da
apis.google.com
tramite HTTPS, nonché dall'origine della pagina corrente.
Con questo criterio definito, il browser genera semplicemente un errore anziché caricare lo script da qualsiasi altra origine. Quando un malintenzionato abile riesce a inserire codice nel tuo sito, si imbatte in un messaggio di errore anziché nel messaggio di conferma che si aspettava.
I criteri si applicano a una vasta gamma di risorse
Sebbene le risorse script siano i rischi per la sicurezza più evidenti, i CSP forniscono un ricco insieme di direttive dei criteri che consentono un controllo abbastanza granulare delle risorse che una pagina può caricare. Hai già visto script-src
, quindi il concetto dovrebbe essere chiaro.
Vediamo rapidamente il resto delle direttive delle risorse. L'elenco seguente rappresenta lo stato delle istruzioni a partire dal livello 2. È stata pubblicata una specifica di livello 3, ma è in gran parte non implementata nei principali browser.
base-uri
limita gli URL che possono essere visualizzati nell'elemento<base>
di una pagina.child-src
elenca gli URL dei lavoratori e dei 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, WebSocket e EventSource).font-src
specifica le origini che possono pubblicare caratteri web. I caratteri web di Google possono essere attivati tramitefont-src https://themes.googleusercontent.com
.form-action
elenca gli 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 direttiva non può essere utilizzata nei tag<meta>
e si applica solo alle risorse non HTML.frame-src
è stato ritirato nel livello 2, ma è stato ripristinato nel livello 3. Se non è presente, utilizza comunquechild-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 direttiva non può essere utilizzata nei tag<meta>
.style-src
è il corrispettivo discript-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
è una direttiva CSP di Livello 3 che limita gli URL che possono essere caricati come worker, worker condiviso o service worker. Da luglio 2017, questa direttiva ha implementazioni limitate.
Per impostazione predefinita, le direttive sono 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 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 una direttiva font-src
, puoi caricare i 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 direttive non utilizzano default-src
come opzione di riserva. Ricorda che se non le imposti, è come se consentissi tutto.
base-uri
form-action
frame-ancestors
plugin-types
report-uri
sandbox
Puoi utilizzare quante più o meno di queste direttive sono necessarie per la tua applicazione specifica, elencandole semplicemente nell'intestazione HTTP, separando le direttive con i punti e virgola. Assicurati di elencare tutte
le risorse richieste di un tipo specifico in una singola direttiva. Se scrivevi qualcosa come script-src https://host1.com; script-src https://host2.com
, la seconda direttiva veniva semplicemente ignorata. Un valore simile al seguente specifica correttamente entrambe le origini come valide:
script-src https://host1.com https://host2.com
Ad esempio, se 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 contenuti o plug-in incorniciati, le tue norme potrebbero essere simili alle seguenti:
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 che devi utilizzare.
Indipendentemente dall'intestazione utilizzata, le norme vengono definite su base pagina: dovrai inviare l'intestazione HTTP insieme a ogni risposta di cui vuoi assicurarti la protezione. 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 presenti un pulsante +1, e altre no: puoi consentire il caricamento del codice del pulsante solo quando necessario.
L'elenco di origini in ogni istruzione è flessibile. Puoi specificare le origini in base allo schema (data:
, https:
) o in base a una specificità che va da solo nome host (example.com
, che corrisponde a qualsiasi origine su quell'host: qualsiasi schema, qualsiasi porta) a un URI completamente qualificato (https://example.com:443
, che corrisponde solo a HTTPS, soloexample.com
e solo alla porta 443). I caratteri jolly sono accettati, ma solo come schema,
una porta o nella posizione più a sinistra del nome host: *://*.example.com:*
corrisponderebbe
a tutti i sottodomini di example.com
(ma non al valore example.com
stesso), utilizzando
qualsiasi schema, su qualsiasi porta.
L'elenco delle origini accetta anche quattro parole chiave:
'none'
, come previsto, non corrisponde a nulla.'self'
corrisponde all'origine corrente, ma non ai relativi sottodomini.'unsafe-inline'
consente JavaScript e CSS in linea. (Ne parleremo più in dettaglio tra poco.)'unsafe-eval'
consente meccanismi di conversione di testo in JavaScript comeeval
. Ci occuperemo anche di questo.
Queste parole chiave richiedono 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 direttiva che vale la pena di menzionare: sandbox
. È un po' diversa dalle altre che abbiamo esaminato, in quanto impone limitazioni alle azioni che la pagina può intraprendere anziché alle risorse che 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. Sebbene non rientri nell'ambito di questo articolo, puoi trovare tutti i dettagli sugli attributi di sandboxing validi nella sezione "Sandboxing" 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. A tale scopo, 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 utilizzato per frame-ancestors
, report-uri
o sandbox
.
Il codice in linea è considerato dannoso
È chiaro che il CSP si basa sulle origini della lista consentita, in quanto è un modo non ambiguo per indicare al browser di trattare insiemi specifici di risorse come accettabili e di rifiutare il resto. Tuttavia, le liste consentite basate sulle origini non risolvono la più grande minaccia rappresentata dagli attacchi XSS: l'iniezione di script in linea.
Se un malintenzionato riesce a iniettare un tag script che contiene direttamente un payload malevolo (<script>sendMyDataToEvilDotCom();</script>
), il browser non ha alcun meccanismo per distinguerlo da un tag script inline legittimo. CSP risolve il problema escludendo completamente lo script
in linea: è l'unico modo per esserne sicuro.
Questo divieto include non solo gli script incorporati direttamente nei tag script
, ma anche gli URL javascript:
e i gestori degli eventi in linea. Dovrai spostare i contenuti dei tag script
in un file esterno e sostituire gli URL javascript:
e <a ... onclick="[JAVASCRIPT]">
con chiamate addEventListener()
appropriate. Ad esempio,
puoi riscrivere quanto segue:
<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 presenta una serie di vantaggi oltre a funzionare bene con CSP; è già una best practice, indipendentemente dall'utilizzo di CSP. Il codice JavaScript in linea mescola struttura e comportamento esattamente nel modo in cui 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 impegni a spostarlo 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 stili in linea, puoi attivarli
aggiungendo 'unsafe-inline'
come origine consentita in una direttiva script-src
o style-src
. Puoi anche utilizzare un nonce o un hash (vedi di seguito), ma ti sconsigliamo di farlo.
Il divieto di script in linea è il più grande vantaggio in termini di sicurezza offerto dai CSP e anche il divieto di stile in linea rafforza la tua applicazione. È necessario un po' di impegno iniziale per assicurarsi che tutto funzioni correttamente dopo aver spostato tutto il codice out-of-line, ma si tratta di un compromesso che vale la pena fare.
Se devi assolutamente utilizzarlo
Il livello 2 del CSP offre la compatibilità con le versioni precedenti per gli script in linea consentendoti di aggiungere script in linea specifici alla lista consentita utilizzando un nonce criptato (numero utilizzato una sola 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 valore deve corrispondere a uno nell'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
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 non devono essere deducibili.
Gli hash funzionano in modo molto simile. 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>
Le tue norme contengono quanto segue:
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='
Ci sono alcuni aspetti da notare. Il prefisso sha*-
specifica l'algoritmo che genera l'hash. Nell'esempio precedente, viene utilizzato sha256-
. Il fornitore di servizi cloud 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 iniziali o finali.
Una ricerca su Google sulla generazione di hash SHA ti condurrà a soluzioni in qualsiasi numero di lingue. Se utilizzi Chrome 40 o versioni successive, puoi aprire DevTools e poi ricaricare la pagina. La scheda Console conterrà i messaggi di errore con l'hash sha256 corretto per ciascuno degli script in linea.
Valuta anche
Anche se un malintenzionato non può iniettare direttamente lo script, potrebbe essere in grado di ingannare la tua applicazione per farle convertire il testo altrimenti inerte in JavaScript 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 del CSP a questo rischio è bloccare completamente tutti questi vettori.
Ciò ha diversi impatti sul modo in cui crei le applicazioni:
- Devi analizzare JSON tramite
JSON.parse
integrato, anziché fare affidamento sueval
. Le operazioni JSON native sono disponibili in tutti i browser a partire da IE8 e sono completamente sicure. - Riscrivi le chiamate
setTimeout
osetInterval
attualmente in corso con le funzioni in linea anziché con le stringhe. Ad esempio:
setTimeout("document.querySelector('a').style.display = 'none';", 10);
sarebbe meglio scritto come:
setTimeout(function () {
document.querySelector('a').style.display = 'none';
}, 10);
- Evita i modelli in linea in fase di esecuzione: molte librerie di modelli utilizzano
new Function()
liberamente per velocizzare la generazione dei modelli in fase di esecuzione. Si tratta di un'applicazione ingegnosa della programmazione dinamica, ma comporta il rischio di valutare testo dannoso. Alcuni framework supportano CSP out of the box, ricorrendo a un parser robusto in assenza dieval
. La direttiva ng-csp di AngularJS è un buon esempio.
Tuttavia, una scelta migliore sarebbe un linguaggio di modelli che offre
la precompilazione (ad esempio Handlebars). La precompilazione dei modelli può rendere l'esperienza utente ancora più
veloce rispetto alla più rapida implementazione del runtime, oltre a essere 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 impedisci l'esecuzione di stringhe, un malintenzionato avrà molte più difficoltà a eseguire codice non autorizzato sul tuo sito.
Rapporti
La capacità del CSP di bloccare le risorse non attendibili lato client è un'enorme risorsa per i tuoi utenti, ma sarebbe molto utile ricevere una sorta di notifica inviata al server in modo da poter identificare ed eliminare eventuali bug che consentano l'iniezione di codice dannoso. 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 tracciare 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 stai appena iniziando a utilizzare i CSP, è consigliabile valutare lo stato attuale della tua applicazione prima di implementare criteri draconiani 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;
I criteri specificati in modalità solo report non bloccheranno le risorse con limitazioni, ma invieranno i report sulle violazioni alla posizione specificata. Puoi anche inviare entrambe le intestazioni, applicando una norma e monitorandone un'altra. 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.
Utilizzo reale
CSP 1 è abbastanza utilizzabile in Chrome, Safari e Firefox, ma ha un supporto molto limitato in IE 10. Puoi visualizzare le specifiche su caniuse.com. Il livello 2 di CSP è 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 passaggio per creare un criterio per la tua applicazione è valutare le risorse che stai effettivamente caricando. Quando ritieni di avere capito come vengono messe insieme le cose nella tua app, imposta un criterio in base a questi requisiti. Analizziamo alcuni casi d'uso comuni e vediamo come possiamo supportarli al meglio nei confini protettivi del 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<iframe>
dihttps://plusone.google.com
. Per incorporare il pulsante, devi avere un criterio che includa entrambe queste origini. Un criterio minimo sarebbescript-src https://apis.google.com; child-src https://plusone.google.com
. Inoltre, devi assicurarti che lo snippet di JavaScript fornito da Google venga estratto in un file JavaScript esterno. Se avevi un criterio basato sul livello 1 che utilizzavaframe-src
Il livello 2 richiedeva di impostarechild-src
. Questa operazione non è più necessaria nel livello 3 del CSP.Il pulsante Mi piace di Facebook offre una serie di opzioni di implementazione. Ti consigliamo di utilizzare la versione
<iframe>
, in quanto è in una sandbox al sicuro dal resto del sito. Per il corretto funzionamento è necessaria una direttivachild-src https://facebook.com
. Tieni presente che, per impostazione predefinita, il codice<iframe>
fornito da Facebook carica un URL relativo,//facebook.com
. Modificalo in modo da 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 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.script-src https://platform.twitter.com; child-src https://platform.twitter.com
è tutto pronto, a condizione che tu sposti lo snippet JavaScript fornito da Twitter in un file JavaScript esterno.Altre piattaforme hanno requisiti simili e possono essere gestite in modo simile. Ti consigliamo di impostare un valore
default-src
pari a'none'
e di controllare la console per determinare quali risorse devi attivare per far funzionare i widget.
Includere più widget è semplice: basta combinare le direttive del criterio, ricordandosi di unire tutte le risorse di un singolo tipo in un'unica direttiva. Se volessi tutti e tre i widget per i social media, la norma dovrebbe essere simile alla seguente:
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: lockdown
Supponiamo per un momento che tu gestisca un sito bancario e voglia assicurarti che possano essere caricate solo le risorse che hai scritto tu. In questo scenario, inizia con un criterio predefinito che blocca assolutamente tutto (default-src 'none'
) e poi procedi da lì.
Supponiamo che la banca carichi tutte le immagini, gli stili e gli script da una CDN all'indirizzo
https://cdn.mybank.net
e si connetta tramite XHR a https://api.mybank.com/
per recuperare vari bit di dati. I frame vengono utilizzati, ma solo per le pagine locali del sito (nessuna origine di terze parti). Non sono presenti elementi Flash sul sito, né caratteri né contenuti aggiuntivi. 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 di anelli nuziali vuole assicurarsi che tutte le risorse vengano caricate solo tramite canali sicuri, ma non scrive molto codice. La riscrittura di grandi parti del software del forum di terze parti, pieno zeppo di script e stili in linea, è al di là delle sue capacità. 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
, le direttive 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 consiglio candidato. Il gruppo di lavoro W3C per la sicurezza delle applicazioni web ha già iniziato a lavorare alla prossima versione della specifica, Content Security Policy Level 3.
Se ti interessa la discussione su queste funzionalità imminenti, dai un'occhiata agli archivi della mailing list public-webappsec@ o partecipa tu stesso.