Nelle ultime settimane abbiamo trattato sul blog diverse intestazioni HTTP relative alla sicurezza, ma la più importante di tutte è la Content-Security-Policy(CSP). Il capo, sia per il livello di protezione che offre, ma purtroppo anche per la difficoltà di implementarlo correttamente al primo colpo. Come tutte le regole di gestione del traffico di flightPATH di cui abbiamo parlato di recente, le utilizziamo noi stessi per proteggere il sito web edgeNEXUS e i suoi visitatori.
Abbiamo fatto il duro lavoro e provato il dolore per non costringerti a farlo, ma è innegabile che sia necessaria una certa riflessione e pianificazione prima dell “implementazione. Ma ne vale la pena. Il concetto alla base di questa intestazione è piuttosto semplice e altrettanto potente. In poche parole, lo usi per specificare le origini consentite dei contenuti che possono essere caricati sul tuo sito web. In questo modo si ottiene una forte protezione contro una serie di attacchi di tipo code-injection diffusi nell” Internet sempre più dinamico di oggi, come il Cross Site Scripting (XSS) e il Clickjacking.
I tipi di contenuto che possono essere controllati includono: JavaScript, CSS (sì, i CSS possono essere pericolosi), frame HTML, font, immagini e oggetti incorporabili come le applet Java. È bello avere così tante opzioni, ma è qui che sorge la difficoltà. I siti web di oggi (compresi i nostri) contengono una moltitudine di questi tipi di contenuti provenienti da diverse fonti e identificarli e tenerne conto in un regolamento può essere un’impresa ardua.
Prima di entrare nel merito, diamo un “occhiata agli elementi del valore dell” intestazione e all “aspetto di un criterio. Come vedrai, si tratta essenzialmente di un lungo elenco di tipi di contenuto (che in questo esempio terminano tutti con -src) e delle fonti consentite per ciascun tipo. L” insieme di questi elementi è noto come direttive di policy.
default-src “self” data:; script-src “self” “unsafe-inline”; connect-src “self”; img-src “self” data:; style-src “self” “unsafe-inline” data:; font-src “self” data:; child-src “self”
Ci sono altri tipi di contenuti che possiamo prendere in considerazione, ma quelli mostrati sopra sono le direttive più importanti (secondo noi, in base al rischio e alla diffusione). Ecco i dettagli sui contenuti a cui ciascuno di essi si riferisce;
- default-src – Valori predefiniti per la maggior parte (ma non per tutti) i tipi di contenuto se non specificati successivamente
- script-src – Sorgenti consentite per gli script (incluso JavaScript)
- connect-src – Sorgenti consentite per le connessioni (come WebSockets e EventSource utilizzati, ad esempio, nelle applicazioni di chat).
- img-src – Sorgenti consentite per le immagini
- style-src – Sorgenti consentite per i CSS
- font-src – Sorgenti consentite per i font
- child-src – Sorgenti consentite per frame e iframe
Questi tipi di contenuto e i loro valori sono separati l “uno dall” altro (delimitati) con un punto e virgola. Ogni tipo può avere uno o più dei seguenti valori;
- “none” – non consentire questo tipo di contenuto
- “self” – autorizza questo tipo di contenuto se proviene direttamente da questo sito (ma non dai sottodomini)
- “unsafe-inline” – permette di utilizzare CSS e JavaScript inline (purtroppo è molto comune)
- dati: – consentire l’utilizzo di fonti di dati in linea (tipicamente utilizzate per fornire font e immagini in linea per migliorare le prestazioni)
- https: – consente questo tipo di contenuto solo su HTTPS
- Unsafe-eval” – consente l “analisi del testo utilizzando metodi potenzialmente pericolosi che possono portare all” esecuzione di codice.
- nome-dominio – consente questo tipo di contenuto se proviene dal nome-dominio specificato (in altre parole, un dominio remoto) – questo può essere usato più volte
- * – qualsiasi dominio
Per delimitare ogni valore viene utilizzato un semplice spazio. Gli apici singoli “sono obbligatori a meno che il valore non sia un nome di dominio. Si noti che le estensioni e i plugin del browser sono esenti, in quanto sono considerati sicuri in quanto ritenuti affidabili dall” utente (che li ha installati).
Tutto ciò sembra piuttosto tecnico e complesso, ma se lo affrontiamo un passo alla volta è piuttosto veloce arrivare a una politica. Vediamo rapidamente due esempi. Innanzitutto, proviamo un semplice sito web interno servito via HTTP. Ecco cosa ci serve;
- dati default-src “self”: – consente solo i contenuti del proprio sito, compresi gli oggetti inline
- script-src “self” “unsafe-inline” – consente gli script dal nostro sito, compresi quelli inline
- connect-src “self” – consente le connessioni da/verso il proprio sito
- dati img-src “self”: – consente le immagini dal nostro sito, incluse quelle in linea
- style-src “self” “unsafe-inline” data: – consente di utilizzare il CSS del nostro sito, compresi gli stili in linea
- dati font-src “self”: – permette i font dal nostro sito, compresi quelli in linea
Il valore completo dell’intestazione è ragionevolmente breve:
default-src “self” data:; script-src “self” “unsafe-inline”; connect-src “self”; img-src “self” data:; style-src “self” “unsafe-inline” data:; font-src “self” data:
In secondo luogo, un sito web protetto da SSL/TLS che utilizza Google Analytics (GA), CSS inline, font e immagini, CSS del tuo sito e immagini di altri siti web. Vediamo cosa ci serve pezzo per pezzo (non è molto diverso);
- default-src “self” data: https: – consente solo i contenuti del proprio sito, compresi gli oggetti inline, solo su HTTPS
- script-src “self” “unsafe-inline” https: – consente gli script dal nostro sito, compresi quelli in linea, solo su HTTPS
- img-src “self” “unsafe-inline” \* https: – permette le immagini da qualsiasi sito, comprese quelle inline dal nostro, solo su HTTPS
- style-src “self” “unsafe-inline” https: – permette di utilizzare solo CSS provenienti dal nostro sito, compresi quelli in linea, solo su HTTPS
- font-src “self” “unsafe-inline” https: – consente solo i font dal nostro sito, compresi quelli in linea, solo su HTTPS
Sommando il tutto si ottiene questa polizza leggermente più lunga:
default-src “self” data: https:; script-src “self” “unsafe-inline” *.google-analytics.com https:; img-src “self” “unsafe-inline” * https:; style-src “self” “unsafe-inline” https:; font-src “self” “unsafe-inline” https:
Direi che è abbastanza facile. In passato Google non era così “amichevole” nei confronti del CSP (questo valore dell’intestazione era lungo almeno il doppio), ma fortunatamente negli ultimi tempi ha fatto passi da gigante. Noterai che non abbiamo dovuto aggiungere il dominio *.google-analytics.com allo script-src come valore del tipo di contenuto, poiché il loro codice viene eseguito come script inline.
L’ideale sarebbe creare un criterio per ogni pagina del tuo sito web, dato che le risorse caricate variano senza dubbio da una pagina all’altra, ma questo è piuttosto oneroso ed è molto più semplice, ma comunque efficace, creare un criterio che copra tutte le possibili fonti. La maggior parte degli esempi presenti sulla nostra pagina GitHub seguono questo approccio, ma ce n’è anche uno che ti permette di fornire una maggiore protezione a pagine specifiche.
Per i test e la risoluzione dei problemi, ti consiglio di utilizzare gli Strumenti per sviluppatori di Google Chrome. Vai al sito in questione, premi F12, clicca su Rete, assicurati che sia spuntata la voce Disattiva cache e poi ricarica la pagina. Eventuali errori saranno evidenziati chiaramente. In fondo a questo blog c’è una schermata di ciò che potresti vedere se il tuo criterio blocca unsafe-inline e stai usando Google Analytics; i messaggi di errore sono molto utili.
Regola i tuoi criteri se necessario e ripeti l “operazione. L” ideale sarebbe utilizzare un servizio virtuale di prova dedicato con la regola flightPATH applicata, ma che serva lo stesso sito, solo attraverso un IP virtuale diverso, in modo da non influenzare i clienti reali durante i test.
Come sempre, l “enorme vantaggio dell” utilizzo di un bilanciatore di carico è che dobbiamo effettuare queste operazioni in un unico punto centrale per proteggere tutti i nostri server (e siti). Non dobbiamo affidarci a sviluppatori o a riconfigurazioni del server web. Sul bilanciatore di carico edgeNEXUS dobbiamo semplicemente importare un modello di configurazione automatica jetPACK e assegnare una regola di traffico flightPATH a qualsiasi Servizio Virtuale che desideriamo proteggere (dopo le opportune modifiche).
La regola aggiunge l’intestazione solo se non esiste, quindi funzionerà anche se i nostri server web la inseriscono già o magari la inseriscono solo per pagine specifiche. Questa regola dovrebbe far parte della configurazione standard del tuo Servizio Virtuale: non hai nulla da perdere, qualunque sia il sito, anche se ovviamente è sempre consigliabile fare delle prove. Puoi scaricare questo jetPACK e molti altri sul sito Github di edgeNEXUS.
flightPATH è un motore di regole dinamico e basato sugli eventi sviluppato da edgeNEXUS per manipolare e instradare in modo intelligente il traffico IP, HTTP e HTTPS in modo bilanciato. È altamente configurabile e potente, ma molto facile da usare.
Se vuoi saperne di più, vale la pena di leggere questi link correlati;
http://www.html5rocks.com/en/tutorials/security/content-security-policy/
https://developer.mozilla.org/en/docs/Web/Security/CSP/CSP_policy_directives
http://content-security-policy.com/
https://www.clickintelligence.co.uk/header-response-checker/
Nelle ultime settimane abbiamo trattato sul blog diverse intestazioni HTTP relative alla sicurezza, ma la più importante di tutte è la Content-Security-Policy (CSP).