Il Content-Security-Policy
meta-tag consente di ridurre il rischio di attacchi XSS consentendo di definire da dove possono essere caricate le risorse, impedendo ai browser di caricare dati da qualsiasi altra posizione. Ciò rende più difficile per un utente malintenzionato inserire codice dannoso nel tuo sito.
Ho sbattuto la testa contro un muro di mattoni cercando di capire perché stavo ricevendo errori CSP uno dopo l'altro e non sembravano esserci istruzioni concise e chiare su come funziona. Quindi ecco il mio tentativo di spiegare brevemente alcuni punti del CSP, concentrandomi principalmente sulle cose che ho trovato difficile da risolvere.
Per brevità non scriverò il tag completo in ogni campione. Invece mostrerò solo la content
proprietà, quindi un esempio che dice content="default-src 'self'"
significa questo:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
1. Come consentire più fonti?
Puoi semplicemente elencare le tue fonti dopo una direttiva come un elenco separato da spazi:
content="default-src 'self' https://example.com/js/"
Nota che non ci sono virgolette attorno a parametri diversi da quelli speciali , come 'self'
. Inoltre, non esiste due punti ( :
) dopo la direttiva. Solo la direttiva, quindi un elenco di parametri separato da spazi.
Tutto sotto i parametri specificati è implicitamente consentito. Ciò significa che nell'esempio sopra si tratterebbe di fonti valide:
https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js
Questi, tuttavia, non sarebbero validi:
http://example.com/js/file.js
^^^^ wrong protocol
https://example.com/file.js
^^ above the specified path
2. Come usare direttive diverse, cosa fanno ognuna?
Le direttive più comuni sono:
default-src
la politica predefinita per il caricamento di JavaScript, immagini, CSS, caratteri, richieste AJAX, ecc
script-src
definisce fonti valide per file javascript
style-src
definisce fonti valide per file css
img-src
definisce fonti valide per le immagini
connect-src
definisce destinazioni valide per XMLHttpRequest (AJAX), WebSocket o EventSource. Se viene effettuato un tentativo di connessione a un host non consentito qui, il browser emulerà un 400
errore
Ce ne sono altri, ma questi sono quelli di cui probabilmente avrai bisogno.
3. Come utilizzare più direttive?
Definisci tutte le tue direttive all'interno di un meta-tag terminandole con un punto e virgola ( ;
):
content="default-src 'self' https://example.com/js/; style-src 'self'"
4. Come gestire le porte?
Tutto tranne le porte predefinite deve essere consentito esplicitamente aggiungendo il numero di porta o un asterisco dopo il dominio consentito:
content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"
Quanto sopra comporterebbe:
https://ajax.googleapis.com:123
^^^^ Not ok, wrong port
https://ajax.googleapis.com - OK
http://example.com/free/stuff/file.js
^^ Not ok, only the port 123 is allowed
http://example.com:123/free/stuff/file.js - OK
Come ho già detto, puoi anche utilizzare un asterisco per consentire esplicitamente tutte le porte:
content="default-src example.com:*"
5. Come gestire protocolli diversi?
Per impostazione predefinita, sono consentiti solo protocolli standard. Ad esempio per consentire WebSocket ws://
dovrete consentirlo esplicitamente:
content="default-src 'self'; connect-src ws:; style-src 'self'"
^^^ web sockets are now allowed on all domains and ports
6. Come consentire il protocollo file file://
?
Se proverai a definirlo come tale non funzionerà. Invece, lo consentirai con il filesystem
parametro:
content="default-src filesystem"
7. Come utilizzare gli script incorporati e le definizioni di stile?
A meno che non sia esplicitamente consentito, non è possibile utilizzare definizioni di stile in linea, codice all'interno di <script>
tag o in proprietà tag come onclick
. Li consenti in questo modo:
content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"
Dovrai anche consentire esplicitamente immagini in linea con codifica base64:
content="img-src data:"
8. Come consentire eval()
?
Sono sicuro che molte persone direbbero che non lo fai, dal momento che "eval is evil" e la causa più probabile per l'imminente fine del mondo. Quelle persone avrebbero torto. Certo, puoi sicuramente punzonare i buchi principali nella sicurezza del tuo sito con eval, ma ha casi d'uso perfettamente validi. Devi solo essere intelligente su come usarlo. Lo consenti in questo modo:
content="script-src 'unsafe-eval'"
9. Cosa 'self'
significa esattamente ?
Potresti 'self'
voler dire localhost, filesystem locale o qualsiasi cosa sullo stesso host. Non significa nessuno di quelli. Significa fonti che hanno lo stesso schema (protocollo), stesso host e stessa porta del file in cui è definita la politica dei contenuti. Servire il tuo sito su HTTP? Nessun https per te, a meno che tu non lo definisca esplicitamente.
Ho usato 'self'
nella maggior parte degli esempi in quanto di solito ha senso includerlo, ma non è assolutamente obbligatorio. Lascialo fuori se non ne hai bisogno.
Ma aspetta un minuto! Non posso semplicemente usarlo content="default-src *"
e finirlo?
No. Oltre alle ovvie vulnerabilità della sicurezza, anche questo non funzionerà come ti aspetteresti. Anche se alcuni documenti sostengono che consenta qualsiasi cosa, non è vero. Non consente inline o eval, quindi per rendere il tuo sito estremamente vulnerabile, dovresti usare questo:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
... ma confido che non lo farai.
Ulteriori letture:
http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy