Fissazione della sessione - Session fixation
Nella sicurezza della rete informatica, gli attacchi di fissazione della sessione tentano di sfruttare la vulnerabilità di un sistema che consente a una persona di fissare (trovare o impostare) l' identificatore di sessione di un'altra persona . La maggior parte degli attacchi di fissazione della sessione sono basati sul Web e la maggior parte si basa sull'accettazione di identificatori di sessione da URL ( stringa di query ) o dati POST.
Scenari di attacco
Alice ha un conto in bancahttp://unsafe.example.com/
Mallory intende prendere di mira i soldi di Alice dalla sua banca.
Alice ha un ragionevole livello di fiducia in Mallory e visiterà i link che Mallory le invia.
Un semplice scenario di attacco
Scenario semplice:
- Mallory ha stabilito che
http://unsafe.example.com/accetta qualsiasi identificatore di sessione, accetta identificatori di sessione dalle stringhe di query e non ha alcuna convalida di sicurezza.http://unsafe.example.com/non è quindi sicuro. - Mallory invia ad Alice un'e-mail: "Ehi, dai un'occhiata, c'è una nuova fantastica funzione di riepilogo del conto sulla nostra banca,
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID". Mallory sta cercando di fissare il SID aI_WILL_KNOW_THE_SID. - Alice è interessata e visita
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SID. Viene visualizzata la solita schermata di accesso e Alice accede. - Mallory fa visita
http://unsafe.example.com/?SID=I_WILL_KNOW_THE_SIDe ora ha accesso illimitato all'account di Alice.
Attacco tramite SID generato dal server
Un equivoco è che se un server accetta solo identificatori di sessione generati dal server, è al sicuro dalla correzione. Questo è falso .
Scenario:
- Mallory visita
http://vulnerable.example.com/e controlla quale SID viene restituito. Ad esempio, il server potrebbe rispondere:Set-Cookie: SID=0D6441FEA4496C2. - Mallory è ora in grado di inviare ad Alice un'e-mail: "Dai un'occhiata a questa nuova fantastica funzionalità sulla nostra banca,
http://vulnerable.example.com/?SID=0D6441FEA4496C2." - Alice accede, con identificatore di sessione fisso
SID=0D6441FEA4496C2. - Mallory fa visita
http://vulnerable.example.com/?SID=0D6441FEA4496C2e ora ha accesso illimitato all'account di Alice.
Attacchi che utilizzano cookie tra sottodomini
Questo tipo di attacco è simile a un attacco di cookie tra siti, tranne per il fatto che non si basa sulla vulnerabilità del browser dell'utente. Piuttosto, si basa sul fatto che i cookie con caratteri jolly possono essere impostati da un sottodominio e che tali cookie possono influenzare altri sottodomini.
Scenario:
- Un sito web
www.example.comdistribuisce sottodomini a terze parti non attendibili - Una di queste parti, Mallory, che ora controlla
evil.example.com, attira Alice sul suo sito - Una visita per
evil.example.comimpostare un cookie di sessione con il dominio.example.comsul browser di Alice - Quando Alice visita
www.example.comquesto cookie verrà inviato con la richiesta e Alice avrà la sessione specificata dal cookie di Mallory. - Se Alice ora accede, Mallory può usare il suo account.
Quando questo attacco è completo, Mallory può accedere a www.example.comcome Alice.
Non è essenziale che un utente acceda per sfruttare gli attacchi di fissazione della sessione e, sebbene questi attacchi non autenticati non siano vincolati agli attacchi di cookie tra sottodomini, le implicazioni degli attacchi di sottodominio sono rilevanti per questi scenari non autenticati. Ad esempio, Mallory può fornire un URL dal loro sito malvagio, fissando una sessione in uno scenario non autenticato e utilizzare tali tecniche per sfruttare il proprio obiettivo. Ciò include scenari che sfruttano sia gli scenari non autenticati (ad esempio moduli o registrazione) sia la possibilità di fornire all'utente una sessione stabilita per bypassare completamente il login.
Si consideri, ad esempio, che Mallory possa creare un utente A1ice su www.example.com e accedere a quell'utente per acquisire un identificatore di sessione corrente e valido. Mallory quindi intrappola Alice con un URL da evil.example.com che fissa quel cookie di sessione nel browser di Alice (come descritto sopra) e reindirizza a www.example.com per finalizzare una particolare transazione (o, di fatto, un uso più ampio). Mallory è quindi in grado di eseguire il ghosting della sessione dal suo login originale, raschiando i dati ed eseguendo operazioni come "A1ice" su "www.example.com". Se Alice è stata ingannata con successo e ha salvato la sua carta di credito sul conto, Mallory potrebbe quindi effettuare acquisti utilizzando quella carta.
Contromisure
Non accettare identificatori di sessione dalle variabili GET/POST
Gli identificatori di sessione in URL (stringa di query, variabili GET) o variabili POST non sono consigliati in quanto semplificano questo attacco: è facile creare collegamenti o moduli che impostano variabili GET / POST.
- Il SID viene divulgato ad altre persone mentre gli utenti tagliano e incollano "link interessanti" dalla barra degli indirizzi in chat, forum, comunità, ecc.
- Il SID è memorizzato in molti posti (registro della cronologia del browser, registro del server Web, registri del proxy, ...)
Nota: i cookie sono condivisi tra le schede e le finestre del browser visualizzate. Se il tuo sistema richiede di essere colpito con lo stesso dominio (www.example.com/?code=site1 e www.example.com/?code=site2 ), i cookie potrebbero entrare in conflitto tra le schede.
Potrebbe essere necessario inviare l'identificatore di sessione sull'URL per superare questa limitazione. Se possibile usa site1.example.com o site2.example.com in modo che non ci siano conflitti di dominio nei cookie. Ciò potrebbe comportare costi con certificati SSL aggiuntivi.
Questo comportamento può essere visto su molti siti aprendo un'altra scheda e provando a fare risultati di ricerca fianco a fianco. Una delle sessioni diventerà inutilizzabile.
Soluzione migliore: conferma dell'identità
Questo attacco può essere ampiamente evitato modificando l'ID di sessione quando gli utenti effettuano l'accesso. Se ogni richiesta specifica di un utente richiede che l'utente sia autenticato ("loggato") al sito, un utente malintenzionato dovrebbe conoscere l'ID della vittima sessione di accesso. Quando la vittima visita il collegamento con l'id di sessione fisso, tuttavia, dovrà accedere al proprio account per fare qualcosa di "importante" come se stessa. A questo punto, il loro ID di sessione cambierà e l'attaccante non sarà in grado di fare nulla di "importante" con l'ID di sessione anonimo.
Una tecnica simile può essere utilizzata per risolvere il problema del phishing . Se l'utente protegge il proprio account con due password, può essere risolto in larga misura.
Questa tecnica è utile anche contro gli attacchi di falsificazione di richieste tra siti .
Soluzione: memorizzare gli identificatori di sessione nei cookie HTTP
L'identificatore di sessione sulla maggior parte dei sistemi moderni è memorizzato per impostazione predefinita in un cookie HTTP , che ha un livello di sicurezza moderato purché il sistema di sessione ignori i valori GET/POST. Tuttavia, questa soluzione è vulnerabile alla falsificazione di richieste tra siti e non soddisfa i requisiti di apolidia di REST .
Soluzione: utilizzare l'identificatore di sessione SSL/TLS
Quando si abilita la sicurezza HTTPS , alcuni sistemi consentono alle applicazioni di ottenere l' identificatore di sessione SSL/TLS . L'uso dell'identificatore di sessione SSL/TLS è molto sicuro, ma molti linguaggi di sviluppo web non forniscono solide funzionalità integrate per questo.
Rigenera SID su ogni richiesta
Una contromisura contro la fissazione della sessione consiste nel generare un nuovo identificatore di sessione (SID) su ogni richiesta. In tal caso, anche se un utente malintenzionato può indurre un utente ad accettare un SID noto, il SID non sarà valido quando l'aggressore tenterà di riutilizzare il SID. L'implementazione di un tale sistema è semplice, come dimostrato da quanto segue:
- Ottieni l'identificatore di sessione precedente
OLD_SIDdalla richiesta HTTP. - Se
OLD_SIDè null, vuoto o nonOLD_SIDesiste alcuna sessione con SID= , crea una nuova sessione. - Genera un nuovo identificatore di sessione
NEW_SIDcon un generatore di numeri casuali sicuro. - Lascia che la sessione sia identificata da SID=
NEW_SID(e non più da SID=OLD_SID) - Trasmettere il nuovo SID al client.
Esempio:
Se Mallory riesce a convincere Alice a visitare http://victim.example.com/?SID=I_KNOW_THE_SID, questa richiesta HTTP viene inviata a victim.example.com:
GET /?SID=I_KNOW_THE_SID HTTP/1.1
Host: victim.example.com
victim.example.comaccetta SID=I_KNOW_THE_SID, che normalmente sarebbe negativo. Tuttavia, victim.example.comè sicuro perché esegue la rigenerazione della sessione. victim.example.comottiene la seguente risposta:
HTTP/1.1 200 OK
Set-Cookie: SID=3134998145AB331F
Alice ora userà SID=3134998145AB331Fquello che è sconosciuto a Mallory e SID=I_KNOW_THE_SIDnon è valido. Mallory non ha quindi successo nel tentativo di fissare la sessione.
Purtroppo la rigenerazione della sessione non è sempre possibile. È noto che si verificano problemi quando vengono utilizzati software di terze parti come ActiveX o applet Java e quando i plug-in del browser comunicano con il server. Il software di terze parti potrebbe causare la disconnessione o la sessione potrebbe essere suddivisa in due sessioni separate.
Se l'implementazione delle sessioni include la trasmissione del SID tramite variabili GET o POST, ciò potrebbe anche rendere inutilizzabile il pulsante "indietro" nella maggior parte dei browser, poiché l'utente utilizzerebbe un identificatore di sessione precedente e non valido da una richiesta precedente.
Accetta solo SID generati dal server
Un modo per migliorare la sicurezza è non accettare identificatori di sessione che non sono stati generati dal server. Tuttavia, come notato sopra, ciò non impedisce tutti gli attacchi di fissazione della sessione.
if (!isset($_SESSION['SERVER_GENERATED_SID'])) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['SERVER_GENERATED_SID'] = true;
Funzione di disconnessione
Una funzione di logout è utile in quanto consente agli utenti di indicare che una sessione non deve consentire ulteriori richieste. Quindi gli attacchi possono essere efficaci solo mentre una sessione è attiva. Si noti che il codice seguente non esegue controlli di falsificazione delle richieste tra siti , consentendo potenzialmente a un utente malintenzionato di costringere gli utenti a disconnettersi dall'applicazione web.
if (logout) {
session_destroy(); // Destroy all data in session
}
Timeout vecchi SID
Questa difesa è semplice da implementare e ha il vantaggio di fornire una misura di protezione contro gli utenti non autorizzati che accedono all'account di un utente autorizzato utilizzando una macchina che potrebbe essere stata lasciata incustodita.
Memorizza una variabile di sessione contenente un timestamp dell'ultimo accesso effettuato da quel SID. Quando quel SID viene riutilizzato, confronta il timestamp corrente con quello memorizzato nella sessione. Se la differenza è maggiore di un numero predefinito, diciamo 5 minuti, distruggi la sessione. Altrimenti, aggiorna la variabile di sessione con il timestamp corrente.
Distruggi la sessione se il referente è sospetto
Quando si visita una pagina, la maggior parte dei browser Web imposterà l' intestazione Referrer , ovvero la pagina che conteneva il collegamento seguito per accedere a questa pagina.
Quando l'utente ha effettuato l'accesso a un sito a cui non è probabile che sia collegato dall'esterno di tale sito (ad esempio, siti Web bancari o webmail ) e il sito non è il tipo di sito in cui gli utenti rimarrebbero collegati per un lungo periodo di tempo volta, il Referente dovrebbe provenire da quel sito. Qualsiasi altro Referente dovrebbe essere considerato sospetto. Tuttavia, se la richiesta di origine proviene da una pagina HTTPS, il referrer verrà rimosso, quindi non puoi dipendere da questo sistema di sicurezza.
Ad esempio, http://vulnerable.example.com/potrebbe impiegare il seguente controllo di sicurezza:
if (strpos($_SERVER['HTTP_REFERER'], 'http://vulnerable.example.com/') !== 0) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
Verificare che le informazioni aggiuntive siano coerenti durante la sessione
Un modo per migliorare ulteriormente la sicurezza è garantire che l'utente sembri essere lo stesso utente finale (client). Ciò rende un po' più difficile eseguire la fissazione della sessione e altri attacchi.
Man mano che sempre più reti iniziano a conformarsi alla RFC 3704 e ad altre pratiche anti- spoofing , l' indirizzo IP diventa più affidabile come identificatore della "stessa fonte". Pertanto, la sicurezza di un sito Web può essere migliorata verificando che l'indirizzo IP di origine sia coerente per tutta la sessione.
Questo potrebbe essere eseguito in questo modo:
if ($_SERVER['REMOTE_ADDR'] != $_SESSION['PREV_REMOTEADDR']) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['PREV_REMOTEADDR'] = $_SERVER['REMOTE_ADDR'];
Tuttavia, ci sono alcuni punti da considerare prima di utilizzare questo approccio.
- Diversi utenti possono condividere un indirizzo IP. Non è raro che un intero edificio condivida un indirizzo IP utilizzando NAT .
- Un utente potrebbe avere un indirizzo IP incoerente. Questo è vero per gli utenti dietro i proxy (come i clienti AOL ). È vero anche per alcuni utenti mobili/in roaming, così come per gli utenti che hanno connessioni Internet con bilanciamento del carico. Gli utenti con le estensioni di privacy IPv6 abilitate possono anche modificare i propri indirizzi di privacy IPv6 in qualsiasi momento.
- Non funzionerà in modo affidabile con i client dual stack poiché le richieste si sposteranno tra IPv4 e IPv6.
- Non funzionerà in modo affidabile con gli utenti mobili, poiché anche gli utenti mobili si spostano tra gli indirizzi.
Per alcuni siti, la sicurezza aggiuntiva supera la mancanza di comodità, mentre per altri no.
Agente utente
I browser si identificano tramite intestazioni HTTP "User-Agent". Questa intestazione normalmente non cambia durante l'uso; sarebbe estremamente sospetto se ciò accadesse. Un'applicazione Web potrebbe utilizzare il rilevamento User-Agent nel tentativo di impedire a utenti malintenzionati di rubare sessioni. Tuttavia, questo è banale da aggirare, poiché un utente malintenzionato può facilmente catturare l'agente utente della vittima con il proprio sito e quindi falsificarlo durante l'attacco. Questo sistema di sicurezza proposto si basa sulla sicurezza attraverso l'oscurità .
if ($_SERVER['HTTP_USER_AGENT'] != $_SESSION['PREV_USERAGENT']) {
session_destroy(); // Destroy all data in session
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
Tuttavia, ci sono alcuni punti da considerare prima di utilizzare questo approccio.
- Diversi utenti possono avere lo stesso agente utente del browser in Internet café .
- Diversi utenti possono avere lo stesso browser predefinito (es: Internet Explorer 6 in Windows XP SP3 o mini browser nel telefono cellulare).
Ma l'agente utente può cambiare legalmente in alcuni casi. I seguenti esempi sono gli stessi utenti.
- Uno smartphone il cui schermo ha ruotato dall'ultima richiesta
Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 854X480 motorola DROID2Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 Build/VZW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 480X854 motorola DROID2
- Modalità di compatibilità con Internet Explorer:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
- Un utente che accede a un sito Web tramite un proxy distribuito su più server, non tutti aggiornati all'ultima versione del software proxy
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/0.0.5; +http://flipboard.com/browserproxy)Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/1.1; +http://flipboard.com/browserproxy)
Difesa in profondità
La difesa in profondità consiste nel combinare diverse contromisure. L'idea è semplice: se un ostacolo è banale da superare, molti ostacoli potrebbero essere molto difficili da superare.
Una strategia di difesa in profondità potrebbe comportare:
- Abilita HTTPS (per proteggersi da altri problemi)
- Configurazione corretta (non accettare SID esterni, impostare timeout, ecc.)
- Eseguire session_regeneration, supportare il logout, ecc.
I referrer HTTP non vengono passati con SSL/TLS (HTTPS).
Il seguente script PHP dimostra diverse di queste contromisure combinate in modo approfondito:
if (isset($_GET['LOGOUT']) ||
$_SERVER['REMOTE_ADDR'] !== $_SESSION['PREV_REMOTEADDR'] ||
$_SERVER['HTTP_USER_AGENT'] !== $_SESSION['PREV_USERAGENT']) {
session_destroy();
}
session_regenerate_id(); // Generate a new session identifier
$_SESSION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['PREV_REMOTEADDR'] = $_SERVER['REMOTE_ADDR'];
Tieni presente che questo codice controlla l'attuale REMOTE_ADDR (l'indirizzo IP dell'utente) e l'agente utente rispetto a REMOTE_ADDR e agente utente della richiesta precedente. Questo potrebbe essere scomodo per alcuni siti come discusso sopra.
Guarda anche
Riferimenti
link esterno
- Angolo della sicurezza: fissazione della sessione
- Vulnerabilità della fissazione della sessione nelle applicazioni basate sul Web (PDF)
- Esempio di video sulla fissazione della sessione
- Classificazione delle minacce del Web Application Security Consortium