Le applicazioni Web sono spesso bersaglio di malintenzionati. Queste applicazioni sono pubblicamente accessibili - o almeno lo sono le loro pagine di login - e non è difficile per un attaccante determinato trovare siti con falle di sicurezza. Gli aggressori spesso cercano di sfruttare le vulnerabilità della pagina di login in un'applicazione Web per causare un carico eccessivo e potenzialmente far crollare il sito.
Una di queste vulnerabilità si trova nella pagina delle domande di sicurezza che fa parte di molti flussi di login. In questo post analizzeremo questo scenario, esamineremo i motivi del problema e forniremo indicazioni su come mitigare il rischio di sicurezza.
La pagina di accesso con una domanda di sicurezza vuota
Le vulnerabilità della pagina di login sono più comuni di quanto si possa pensare. Nel processo di login di molti siti web e applicazioni, una verifica aggiuntiva estende il tradizionale passaggio nome utente/password per aumentare la sicurezza. Immaginate un flusso di login in due fasi. Nella prima fase, il sito chiede una combinazione di nome utente e password. Se queste credenziali vengono inserite correttamente, il secondo passaggio chiede di rispondere a una domanda di sicurezza (specificata al momento della prima configurazione dell'account).
Questo secondo passaggio è in genere costruito da un modello di visualizzazione della pagina che inserisce la domanda di sicurezza in base all'utente che ha completato con successo il primo passaggio. L'intero flusso di login in due fasi funziona fondamentalmente così:
- Alice visita la pagina di login di https://www.example.com/login.
- Alice invia una combinazione di nome utente e password.
- Il server verifica le credenziali inviate.
- Poiché le credenziali erano corrette, il server reindirizza il browser alla pagina di follow-up all'indirizzo https://www.example.com/login2, includendo un token unico nell'intestazione della richiesta per verificare che Alice abbia superato la prima fase del flusso di login.
- Il server esegue il rendering di questa pagina sulla base di un modello, inserendo la domanda di sicurezza recuperata per Alice, insieme all'input di testo per la risposta e a un pulsante di invio.
- Alice invia la risposta alla sua domanda di sicurezza.
- Il server verifica che Alice abbia risposto correttamente alla domanda di sicurezza e quindi effettua il login.
Concentriamoci sulla seconda pagina del flusso, all'indirizzo https://www.example.com/login2. Immaginate cosa potrebbe accadere se visitaste quella pagina direttamente nel vostro browser, senza passare per il primo passo.
In uno scenario, è possibile che il server verifichi l'assenza di un token valido nell'intestazione della richiesta (il che significa che l'utente non ha superato con successo la prima fase del flusso di login) e si limiti a reindirizzare l'utente a https://www.example.com/login per ricominciare da capo.
Tuttavia, in un altro possibile scenario, il server continua a rendere la pagina in base al modello. Non riuscendo a trovare una domanda di sicurezza corrispondente per l'utente (poiché non c'è un token che indichi al server di quale utente autenticato a metà si tratta), la pagina risultante potrebbe apparire come questa:
Ci si ritrova con un'imbarazzante pagina di domande di sicurezza che... non ha domande di sicurezza. Si tratta di una pagina inutile.
Inutile, sì. Ma innocuo? Non siate così sicuri.
Le implicazioni per la sicurezza
Continuando con questo scenario, cosa accadrebbe quando voi (o una persona più malintenzionata di voi) inviate una risposta a questa "domanda di sicurezza"? Il server dedicherà cicli di CPU per valutare la risposta. Elaborerà l'input di testo, cercherà il token univoco nell'intestazione della richiesta e forse eseguirà anche una query di database nel tentativo di convalidare la risposta.
Una pagina di login con una domanda di sicurezza vuota può sembrare di poco conto(che male c'è a sprecare qualche ciclo di CPU qua e là?), ma può portare a seri problemi di sicurezza.
- Spreco di risorse di elaborazione del backend: L'elaborazione di moduli inutili consuma risorse di rete e di calcolo, e forse anche risorse di database.
- Potenziale di attacchi denial of service (DoS): Un aggressore potrebbe creare una botnet per inviare ripetutamente i moduli, sovraccaricando il sistema.
- Aumento della vulnerabilità: Un attacco DoS riuscito potrebbe mettere fuori uso l'intero sistema.
Se gli aggressori riescono a sfruttare questa debolezza per sprecare la potenza di elaborazione di un server, potrebbero potenzialmente interrompere i servizi per gli utenti legittimi ed esporre il sistema a ulteriori attacchi.
Non è poi così innocuo.
Vediamo come affrontare vulnerabilità come queste per mantenere la sicurezza e l'affidabilità delle vostre applicazioni.
Come difendersi
Per questo scenario specifico, il server che gestisce l'endpoint login2 deve verificare l'esistenza di un token valido nell'intestazione della richiesta. In assenza di un token valido, non si dovrebbe procedere a ulteriori elaborazioni e l'utente dovrebbe essere reindirizzato alla prima fase del flusso di login. In questo modo, si riducono al minimo le risorse utilizzate per gestire la richiesta con garbo, proprio come nel caso di un 404 o di un 401.
Tuttavia, questo scenario mette in luce un problema di sicurezza più generale a cui dovreste prestare attenzione: le richieste ripetute che sovraccaricano il vostro server. Certamente, lo sfruttamento di una pagina di login inutile con una domanda di sicurezza vuota può sovraccaricare il vostro server più rapidamente a causa della quantità di risorse di elaborazione utilizzate. Ma una botnet può anche colpire la vostra normalissima pagina di login con nome utente/password con richieste eccessive.
Per proteggere le applicazioni Web da questo tipo di attacchi, implementate le seguenti misure:
- Utilizzare un firewall per applicazioni web (WAF): Un WAF può fornire protezione DoS e rilevare e bloccare bot dannosi, riducendo il rischio di attacchi automatici. Il marketplace delle applicazioni di Linode include il WAF comunitario Haltdos, che potrebbe aiutarvi in questo senso.
- Implementare il rate limiting: Limitare il numero di richieste che un singolo indirizzo IP può effettuare in un determinato intervallo di tempo. Con il rate limiting, si impedisce agli aggressori (e ai bot) di inondare il sistema di richieste.
- Attivare il monitoraggio e gli avvisi: Gli strumenti di monitoraggio continuo possono essere alla ricerca di modelli di richiesta sospetti, avvisandovi in tempo reale di potenziali attacchi. Quando si riceve una notifica immediata, è possibile reagire e ridurre rapidamente un problema.
Conclusione
Abbiamo esaminato il caso di una pagina di login con una domanda di sicurezza vuota. A prima vista, sembra uno strano caso limite di pagina, in definitiva inutile. Ma gli aggressori possono sfruttare vulnerabilità come queste per sprecare le vostre risorse e potenzialmente mandare in tilt il vostro sistema. La pagina della domanda di sicurezza è solo un esempio di tale vulnerabilità.
Se progettate le vostre applicazioni tenendo conto della sicurezza e adottate pratiche di codifica sicure, siete già a buon punto. Tuttavia, le vostre applicazioni necessitano anche di misure di sicurezza implementate a livello di sistema e di infrastruttura, come l'utilizzo di un WAF, la limitazione della velocità, il monitoraggio continuo e gli avvisi. Con le misure di sicurezza adeguate, è possibile ridurre significativamente il rischio di essere bersaglio di tali attacchi.
Per ulteriori indicazioni e suggerimenti sulla protezione delle applicazioni, consultare i documenti di Linode, con la sua ricca libreria di guide sulla sicurezza. Lì troverete risorse utili che vi indirizzeranno su come proteggere i vostri sistemi e i vostri utenti.
Commenti