Vai al contenuto

La sicurezza web dal punto di vista di uno sviluppatore

Esistono molte situazioni per cui bisogna preoccuparsi della propria sicurezza nel Web. Per citarne alcuni, ad esempio:

  • Sei un utente che giustamente è preoccupato per la sicurezza dei propri dati personali
  • Sei uno sviluppatore web interessato a rendere le proprie app web più sicure
  • Sei uno sviluppatore web che vuole saper rispondere alle eventuali domande sulla sicurezza web in un colloquio di lavoro…

L’obiettivo di questo post è quello di illustrare alcuni acronimi comuni di sicurezza Web in un modo facile da capire ma comunque accurato. Ma prima di farlo, fissiamo un paio di concetti fondamentali di sicurezza.

La sicurezza non è così semplice

  • Nessuno è mai sicuro al 100%. Non vi è alcuna idea di essere protetti al 100% dall’essere hackerati. Se qualcuno ti da la garanzia di ciò, molto probabilmente è un bugiardo…
  • Uno strato di protezione non è sufficiente. Non è che, ad esempio, una corretta definizione del CSP (Content Security Policy), ti da la garanzia di essere al sicuro al 100%. E vero che in questo modo si può sostanzialmente eliminare lo scripting cross-site dell’elenco delle vulnerabilità, ma ciò potrebbe non bastare.

Cross-Origin Resource Sharing (CORS)

Hai mai ricevuto un errore simile a questo?

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

Non sei il sotlo. Poi vai su Google, cerchi un po’ di soluzioni e qualcuno ti consiglia di installare qualche estensione per Chrome che farà andare via tutti i tuoi problemi! Non è bello tutto ciò? NO!

CORS è lì per proteggerti, non per farti del male!

Per spiegare il CORS, parliamo prima dei cookie di autenticazione. Questi particolari cookievengono utilizzati per comunicare a un server che si è effettuato l’accesso e vengono automaticamente inviati con qualsiasi richiesta effettuata su quel server.

Supponiamo che tu abbia effettuato l’accesso a Facebook utilizzando i cookie di autenticazione. Ad un certo punto apri un sito malevolo in cui vi sia un rendirizamento nascosto ad un altro sito www.supergeniodelmale.com. All’interno di questo sito si trova uno script che effettua una richiesta lato client a facebook.com cui invia il tuo cookie di autenticazione!

In un mondo no-CORS, potrebbero apportare modifiche al tuo account senza che tu lo sappia. Ciò significa che malintenzionati potrebbero pubblicare sulla tua bacheca il link malevolo che hai aperto prima (e che contiene lo script potenzialmente distruttivo), e poi pubblicare lo stesso link sulle bacheche dei tuoi amici, cosi da espandersi come un virus… e il mondo cadrebbe ai piedi di supergeniodelmale.com

Tuttavia, in un mondo CORS, Facebook consentirebbe solo le richieste con un’origine di facebook.com. In altre parole, limiterebbero la condivisione delle risorse tra le origini. Ma che succede se supergeniodelmale.com provasse a modificare l’header di origine della loro richiesta, in modo che sembri provenire da facebook.com? Non funzionerà perchè il browser sa qual è la sua vera origine e semplicemente ignorerà la richiesta.

Content Security Policy (CSP)

Per capire il CSP, dobbiamo prima parlare di una delle vulnerabilità più comuni sul web: XSS, che sta per scripting cross-site. XSS accade quando un “pirata” inietta JavaScript nel codice lato client. Cosa mai potranno fare? Cambiare un testo da rosso a blu? Supponiamo che un malintenzionato abbia iniettato con successo JavaScript nel codice lato client di un sito Web che stai visitando.

Cosa potrebbe fare di dannoso?

  • Potrebbe fare richieste HTTP a un altro sito fingendo di essere te.
  • Potrebbe aggiungere un tag di ancoraggio che ti manda su un sito web malevolo che sembra identico a quello in cui ti trovi con alcune caratteristiche leggermente diverse.
  • Potrebbe aggiungere un tag script con JavaScript incorporato.
  • Potrebbe aggiungere un tag script che recupera da qualche parte un file JavaScript remoto.
  • Potrebbe aggiungere un iframe che copre per intero il sito benevolo con una pagina uguale dove ti invitano a fare login e lasciare quindi i tuoi preziosi dati di accesso.

Le possibilità sono infinite. CSP cerca di impedire che ciò accada limitando:

  • cosa può essere aperto in un iframe
  • quali fogli di stile possono essere caricati
  • dove possono essere fatte richieste, ecc.

Come funziona? Quando fai clic su un link o digiti un URL del sito web nella barra degli indirizzi, il tuo browser fa una richiesta GET. Alla fine si fa strada verso un server che risponde con una pagina HTML insieme ad alcune intestazioni HTTP. Se sei curioso di sapere quali sono queste intestazioni, apri la scheda Network della console del tuo browser (su Chrome è il tasto F12) e visita alcuni siti web. Potresti vedere un’intestazione di risposta simile a questa:

content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

Questa è la politica di sicurezza del contenuto di facebook.com. Modifichiamolo riga per riga per renderlo più facile da leggere:

content-security-policy:
default-src * data: blob:;
script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';
style-src data: blob: 'unsafe-inline' *;
connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

Ora, abbattere le direttive.

  • default-src limita tutte le altre direttive CSP che non sono esplicitamente elencate.
  • script-src limita gli script che possono essere caricati.
  • style-src limita i fogli di stile che possono essere caricati.
  • connect-src limita gli URL che possono essere caricati usando le interfacce di script, quindi fetch, XHR, ajax, ecc.

Ovviamente ci sono molte più direttive CSP rispetto a queste quattro sopra mostrate. Il browser leggerà l’intestazione CSP e applicherà le direttive a tutto ciò che è contenuto nel file HTML. Se le direttive sono impostate in modo appropriato, consentono solo ciò che è necessario. Se non è presente un’intestazione CSP, allora nulla è limitato. Ovunque ci sia il carattere jolly *, significa che quasiasi cosa sarà permessa.

HTTPS o HTTP Secure

Sicuramente hai sentito parlare di HTTPS. E’ la versione crittografata di HTTP. Ma è necessario sempre usarlo? Se il tuo sito è un blog o qualsiasi altro sito in cui l’utente finale non invia al server i suoi dati sensibili, che importa se la connessione è crittografata o meno? Ed ecco che arriva un un nuovo acronimo: MITM, che sta per Man in the Middle.

Se ti trovi in un bar e stai usando il Wi-Fi pubblico senza password, è abbastanza facile per qualcuno agire come se fosse il router a cui sei collegato, in modo che tutte le request e le response passino attraverso di loro. Se i tuoi dati non sono crittografati, allora possono fare quello che vogliono, ad esempio, modificare HTML, CSS o JavaScript prima che la risposta raggiunga il tuo browser. Sulla base di ciò che sappiamo di XSS, puoi immaginare quanto potrebbe essere disastroso.

Ok, ma come è possibile che il mio computer e il server sappiano come crittografare / decifrare ma questo MITM no?

È qui che entrano in gioco SSL (Secure Sockets Layer) e, più recentemente, TLS (Transport Layer Security). TLS ha assunto il ruolo di SSL nel 1999 come tecnologia di crittografia utilizzata in HTTPS. Esattamente come funziona TLS al di fuori dello scopo di questo post.

HTTP Strict-Transport-Security (HSTS)

Usiamo di nuovo l’intestazione di Facebook come esempio:

strict-transport-security: max-age=15552000; preload
  • max-age specifica per quanto tempo un browser deve ricordare di forzare l’utente ad accedere a un sito Web utilizzando HTTPS.
  • preload non è importante per i nostri scopi. È un servizio ospitato da Google e non fa parte delle specifiche HSTS.

Questa intestazione si applica solo se si accede al sito utilizzando HTTPS. Se si accede al sito tramite HTTP, l’intestazione viene ignorata. Il motivo è che, semplicemente, l’HTTP è così insicuro da non poter essere considerato attendibile.

Usiamo l’esempio di Facebook per illustrare ulteriormente come ciò sia utile nella pratica. Accediamo per la prima volta a facebook.com quindi via HTTP. Quando il browser riceve l’HTML, riceve l’intestazione sopra la quale indica al browser di forzare il reindirizzamento a HTTPS per le richieste future. Un mese dopo, qualcuno ti manda un link a Facebook usando HTTP http://facebook.com, e tu fai clic su di esso. Poiché un mese è inferiore ai 15552000 secondi specificati dalla direttiva max-age, il browser invierà la richiesta come HTTPS, impedendo un potenziale attacco MITM.