Nella parte precedente sulla sicurezza PHP abbiamo visto insieme come proteggersi dagli attacchi di injecting (e da altre varianti), ora passo all’argomento "sessione e cookie".
Uno degli attacchi più pericolosi è quello chiamato "session fixation" che permette ad un aggressore di ottenere lo stesso livello di accesso della vittima, per entrare liberamente nell’area privata di un sito e fare così qualsiasi operazione.
Basti pensare a quale danno potrebbe fare un hacker se riuscisse a collegarsi al sito della banca, dove hai il tuo conto online, e potesse operare sui tuoi soldi (prelevare o fare bonifici).
Ma prima voglio illustrarvi che cosa sono la sessione ed i cookie e come funzionano, in modo da comprendere meglio come funzionano gli attacchi ed i metodi per proteggere il proprio sistema PHP.
La sessione per PHP non è nient’altro che un "contenitore" in cui è possibile memorizzare variabili ed oggetti. Questi dati memorizzati nella sessione rimangono validi tra una pagina e l’altra del sito (se rimaniamo nello stesso dominio).
La sessione viene assegnata ad una specifica "sessione di lavoro" del navigatore.
Se io apro sul mio computer due browser, visito un sito con sessione. Le due finestre avranno due sessioni distinte.
Per identificare una sessione dalle altre viene assegnato un ID unico.
Nel caso di un sito con una area privata protetta da password, nel 99% delle implementazioni, viene usata la sessione per mantenere memorizzati i dati dell’accesso, in modo da permettere all’utente di navigare sull’area tra una pagina e l’altra senza perdere i dati del suo login.
Fisicamente la sessione è un file che il server memorizza sul suo disco, se opportunamente configurato si tratta di un file che non può essere raggiunto direttamente da un programma PHP.
Il file di session rimane valido finché la sessione risulta valida, viene "buttato" quando la sessione scade.
Quando scade la sessione?
- dopo un lungo periodo di inattività in cui quella specifica sessione non viene riattivata (vediamo più avanti come si riattiva, non è processo automatico ma viene richiesto tramite comando PHP)
- attraverso un comando PHP per eliminare la sessione corrente
- viene cancellato il file di sessione memorizzato su server
Come si crea o riattiva una sessione?
In PHP la cosa è molto semplice.
Il comando session_start() dice al server di riattivare la sessione oppure, se la sessione non esiste ancora, di crearla.
Dopo il comando sarà possibile utilizzare la sessione tramite la variabile (array) globale $_SESSION.
Per leggere un valore:
echo $_SESSION['nome variabile'];
Per memorizzare un valore nella sessione attuale:
$_SESSION['nome variabile'] = ‘valore’;
Come fa il server a riconoscere la mia sessione?
Per capire quale sia la sessione del visitatore, PHP crea un cookie di nome PHPSESSID che conterrà l’ID unico della sessione.
Nel caso la navigazione avvenga senza cookie è possibile usare un metodo alternativo di richiamo della sessione, per passare l’ID bisogna mettere nell’URL il parametro GID.
Per esempio: http://www.prova.ww/login.php?GID=ii4848nfnjdksn3872nsorffjw3f
Dove sono le vulnerabilità?
Se prendiamo un esempio classico in cui i miei dati di accesso sono memorizzati nella sessione con ID = A1, chiunque si faccia riconoscere dal server con ID = A1 otterrà i miei dati di sessione. (perché il server pensa che sia sempre io)
Prima di questo però è necessario che l’hacker rubi il nostro ID. I metodi per farlo sono abbastanza semplici e veloci (ma evito di metterli per non rendere la vita facile ai buontemponi).
Vi descrivo i due meccanismi principali:
- tramite un attacco di inject, l’hacker si fa spedire (di solito tramite GET) l’ID della sessione utente
- usando il XSS oppure le vulnerabilità dei browser si riesce a leggere i cookie dei domini non di pertinenza e riusciendo così a recupere il cookie con l’ID di sessione
Spesso gli hacker sfruttano il fatto che un utente naviga spesso su più sito contemporaneamente.
Il caso più classico è quello in cui entro nel sito della mia banca quando ho già un’altra finestra browser in cui ho aperto un altro sito (magari poco sicuro).
Se il secondo sito contenesse del codice malevolo, codice dedicato a rubare le sessioni, il sito della banca pur con tutte le protezioni del caso può fare ben poco per evitare questo attacco. (specialmente quello del furto dei cookie)
Un consiglio, quando dovete aprire il sito della vostra banca oppure altri siti di vitale importanza, chiudete tutte le altre finestre, così vi evitate brutte sorprese.
Inoltre fate sempre il logout prima di chiudere il browser, in modo da "annullare" la vostra sessione. Così che chiunque sia riuscito ad avere il vostro ID non possa comunque più far nulla. (in quanto il server non la riconoscerà come sessione valida)
Una volta rubato l’ID all’hacker basta visitare il sito inserendo l’ID della vostra sessione. Nel caso il sistema non sia troppo intelligente assegnerà la vostra sessione all’hacker permettendogli così di fare quello che vuole.
Per fortuna le applicazioni PHP più famose ed utilizzate sono già da tempo sono immuni dalla maggior parte di queste vulnerabilità.
Come possiamo proteggere le nostre applicazioni da questi attacchi?
Analizzando il metodo in cui viene rubato l’ID della sessione, è possibile porre alcuni rimedi per limitare questa vulnerabilità.
Di solito dal momento in cui l’ID viene rubato a quando effettivamente l’hacker lo utilizza passa un po’ di tempo.
Se l’ID cambiasse spesso darebbe nelle mani dell’hacker un ID che dopo pochi minuti risulterebbe non più valido.
In PHP si può (deve) usare la funzione:
session_regenerate_id(TRUE)
In questo modo si obbliga PHP ha rigenerare l’ID di sessione e con il parametro a TRUE, si obbliga a cancellare la vecchia sessione associata al precedente ID.
Consiglio di usare sempre questa funzione in modo da rendere praticamente inutile rubiare l’ID di sessione, solo in casi rarissimi potrebbe dare problemi.
Ecco il flusso di funzionamento di una sessione più resistente ai furti:
session_start() -> carica la sessione attuale, valorizza $_SESSION, oppure se non esiste creane una nuova
session_regenerate_id(TRUE) -> crea un nuovo ID di sessione, mantenendo i valori in $_SESSION, cancella il vecchio ID
Altri problemi con i cookie?
Spesso ho visto in alcuni script PHP che venivano salvate nei cookie un sacco di informazioni più o meno importati.
Come abbiamo visto i cookie sono molto vulnerabili e, spesso grazie a problemi nei browser, gli hacker riescono facilmente a recuperarli e leggerli.
E’ da evitare assolutamente la memorizzazione nei cookie di user e password. Inoltre se dovete memorizzare qualcosa di importante usare la criptazione. (come SHA1 o MD5)
Per evitare che qualcuno mi rubi l’ID oppure i cookie possono verificare l’IP?
E’ uno dei metodi più usati per identificare se l’utente è sempre lo stesso dall’inizio alla fine della navigazione.
In realtà non è però il più affidabile, perché certi provider (specialmente americani), possono rendere dinamico l’IP dell’utente che noi vediamo. In realtà per l’utente il suo IP è sempre lo stesso, ma invece il server potrebbe, in questi casi, vedere cambiare l’IP ogni tanto.
Non è una pazzia del provider, ma un metodo per avere un maggior numero di utente su di un pool limitato di indirizzi internet. (un po’ come fa Fastweb)
Se si vuole legare all’informazione della sessione anche un dato identificato dell’utente è possibile utilizzare l’agent del browser, perché si presume che dall’inizio della navigazione fino alla fine questo non possa cambiare. (stiamo parlando di utente normali e non di sviluppatori che possono modificare inavvertitamente questo valore per i più disparati motivi)
Inoltre è una buona informazione che difficilmente un hacker cerca di emulare.
Nel caso vogliate una protezione potete considerare di verificare l’agent, se cambia invalidate la sessione e riportate l’utente al login.
Tenete però sempre presente che non si tratta di un dato obbligatorio, ci possono essere dei casi in cui il server non lo possa ricevere.
Posted: May 28th, 2008 under Uncategorized.
Comments: none