Diventa Autore per CoreTech | Scopri di più
26/03/20 CoreTech Blog
La memorizzazione nella cache non configurata correttamente può causare varie vulnerabilità. Ad esempio, gli utenti malintenzionati potrebbero utilizzare server intermedi mal configurati (proxy inversi, servizi di bilanciamento del carico o proxy della cache) per ottenere l'accesso a i dati sensibili. Un altro modo per sfruttare la memorizzazione nella cache è attraverso attacchi di avvelenamento da Cache Web.
La cache del browser può apparire come un posto molto sicuro per archiviare temporaneamente le informazioni private. Il rischio principale è che un utente malintenzionato possa accedervi tramite il file system, che di solito è considerato una vulnerabilità a basso rischio. Tuttavia, in alcuni casi, le intestazioni relative alla cache non configurate correttamente possono causare problemi di sicurezza più gravi.
Alcuni siti web hanno diversi sottodomini e hanno la necessità di condividere i dati tra di loro. Ciò normalmente non è possibile a causa della politica sulla stessa origine (SOP). Esistono alcuni metodi che abilitano tale interazione tra domini, ad esempio, JSONP (JSON con Padding). Gli sviluppatori che utilizzano tali metodi devono implementare un qualche tipo di protezione contro la perdita di dati su altri siti.
Diciamo che un sito di esempio ha due sottodomini: blog.example.com e account.example.com. Il sito account.example.com dispone di un endpoint JSONP che restituisce dati sensibili dell’utente in base al cookie dell’utente. Per evitare perdite, questo endpoint verifica l'intestazione Referer
in una whitelist che include blog.example.com.
Con questa configurazione, se l'utente è attirato a visitare un sito dannoso, l'attaccante non può rubare direttamente i dati sensibili. Tuttavia, se l'endpoint JSONP imposta le intestazioni relative alla cache, l'utente malintenzionato potrebbe essere in grado di accedere alle informazioni private dalla cache del browser.
I browser hanno implementazioni della cache leggermente diverse, ma alcuni aspetti sono simili. Innanzitutto, è possibile memorizzare nella cache solo le risposte GET. Quando il browser riceve la risposta alla richiesta GET, controlla le intestazioni di risposta per le informazioni sulla memorizzazione nella cache:
Cache-Control: private
o Cache-Control: public
la risposta viene memorizzata nella cache per Cache-Control: max-age=<seconds>
.Expires
la risposta viene memorizzata nella cache in base al relativo valore (questa intestazione ha meno priorità rispetto a Cache-Control
)Last-Modified
e in genere memorizzare nella cache la risposta per il dieci percento della differenza tra la data corrente e la data Last-Modified
Potrebbero sorgere problemi a causa del fatto che esiste una sola cache del browser per tutti i siti Web e utilizza solo una chiave per identificare i dati: un URI assoluto normalizzato (scheme://host:port/path?query). Ciò significa che la cache del browser non dispone di informazioni aggiuntive sulla richiesta che ha avviato una particolare risposta (ad esempio, il sito/origine da cui proviene, la funzione JavaScript o il tag che l'ha avviata, i cookie o le intestazioni associate, ecc.). Qualsiasi sito ottiene la risposta memorizzata nella cache da account.example.com purché avvii una richiesta GET allo stesso URI.
Di seguito è riportata una spiegazione dettagliata dell'utilizzo di questa vulnerabilità per un attacco:
In questo caso, l'intestazione Referer
non viene mai controllata perché la risposta proviene dalla cache. Pertanto, l'utente malintenzionato ottiene l'accesso alle informazioni private memorizzate nella cache.
Lo stesso approccio può essere utilizzato per sfruttare altre varianti di Cross-Site Script Inclusion (XSSI) e altri attacchi SOP Bypass. Tali attacchi possono ignorare altri controlli sul lato server, ad esempio l'intestazione Origin
l'attributo cookie SameSite
o intestazioni personalizzate.
Supponiamo che account.example.com utilizza Cross-Origin Resource Sharing (CORS) anziché l'endpoint JSONP. Restituisce Access-Control-Allow-Origin: *
ma utilizza un token speciale da un'intestazione personalizzata per autenticare l'utente e proteggere i dati sensibili.
Se le risposte vengono memorizzate nella cache, l'utente malintenzionato può rubare informazioni private effettuando una richiesta allo stesso URI. Non esiste alcuna protezione CORS (a causa di Access-Control-Allow-Origin: *
e il browser dell'utente restituirà i dati memorizzati nella cache senza controllare il token di intestazione personalizzato.
È possibile vedere come funzionano queste vulnerabilità in pratica analizzando gli output della console del browser in un sito di test dedicato.
La vulnerabilità di bypass SOP descritta è causata da una configurazione errata. Nel caso di interazioni tra origini, è necessario disattivare la cache del browser. La maggior parte dei framework e degli script già pronti non imposta le intestazioni relative alla cache o le imposta correttamente per impostazione predefinita (Cache-Control: no-store
). Tuttavia, dovresti sempre controllare queste intestazioni per essere sicuro.
I fornitori di browser stanno ora prendendo in considerazione o implementando un approccio più rigoroso alla memorizzazione nella cache. Speriamo che questo cambiamento prevenga tali perdite di origine incrociata.
Nota – I trucchi inventati ai fini di questo articolo sono stati ispirati dall'articolo HTTP Cache Cross-Site Leaks di Eduardo Vela.