Mysql
 sql >> Database >  >> RDS >> Mysql

La sessione PHP è in conflitto con AJAX

Se ho capito bene, sembra che tu stia impostando il token per ogni richiesta. La mia ipotesi sarebbe che la vecchia pagina abbia ancora il vecchio token. Vorrei controllare se il token è impostato prima di soffiarlo via automaticamente.

 if (isset($_SESSION['token'])){
    //do nothing
 } else{
   $_SESSION['token'] = md5(rand());
 }

Modifica Per rispondere alla tua domanda.

Invece di usare solo una chiave di "token", crea una chiave per ogni sessione del browser.

$_SESSION[$sessionId] = md5(rand());

Il trucco, ovviamente, sarà capire quando si verificano perché se non puoi utilizzare la sessione, non saprai davvero se la richiesta proviene da una nuova scheda o da una vecchia. È possibile utilizzare la stringa di query per passare questo parametro. Fondamentalmente tutte le richieste dovrebbero avere questo parametro altrimenti non si associa ad esse una sessione.

es.

http://www.yoursite.com/somepage.php?sessionid=<some generated id>

In definitiva, l'utente potrebbe scimmiottare con questo, ma non sono sicuro che ci sia un modo per aggirarlo.

Modifica 2 Ok, ecco il mio pensiero su come dovresti farlo. Esperti di sicurezza là fuori, sentiti libero di infiammarmi se sbaglio, come ho detto prima non sono un esperto, ma non sembra che ne uscirò senza suggerire qualcosa;-)

Il problema con CSFR è che un utente malintenzionato, Bob, potrebbe creare un elemento su un altro sito che fa sì che il browser di Alice effettui una richiesta a un altro sito e, poiché Alice aveva effettuato l'accesso in precedenza e tali informazioni vengono memorizzate come cookie o Alice viene riconosciuto tramite sessione, il sito esegue la richiesta come se l'avesse richiesta Alice. Ad esempio, se la banca di Alice è http://www.mybank.com , quindi Bob potrebbe creare un post sul forum che contiene

<img srg="http://www.mybank.com/transferfunds.php?amount=1000&receiver=Bob" />

La banca di Alice riconoscerebbe che il suo browser ha effettuato la richiesta, pensando che sia lei. Ci sono un paio di cose chiave che devono accadere (insieme, una di queste fallire farà fallire l'attacco) per rendere questo un attacco praticabile (queste sono le chiavi per capire come prevenirlo):

  1. Alice deve aver effettuato l'accesso al sito della sua banca in modo che la banca la ricordi. Ciò potrebbe accadere sia in un cookie ("ricordami") o tramite sessione. Tuttavia, se chiude il browser (chiude la sessione) o cancella i cookie, non c'è pericolo perché il sito della banca non la riconoscerà e rifiuterà la richiesta.
  2. Bob deve essere in grado di fornire tutti i parametri necessari alla richiesta, altrimenti il ​​sito della banca rifiuterà la richiesta.

Per fornire una nozione di "stato" su un protocollo senza stato (HTTP), non puoi davvero aggirare il rischio in (1). A meno che tu non faccia sempre clic su "disconnetti" o chiuda la finestra, ecc., non c'è nulla che tu possa fare per evitare di memorizzare le informazioni nel browser o nella sessione. Tuttavia, puoi evitare che (2) sia un problema. La mia soluzione a questo (e sono sicuro che ce ne sono molti altri) è generare un hash, come stai facendo e archiviarlo in sessione.

Ad esempio,

$_SESSION['token'] = md5(rand());

Quindi, quello che fai è aggiungere quel token a tutti i tuoi link interni.

http://www.mysite.com/secure.php?token=giuwnrefviunslfghahgliuwnvwrgbaasd

Tu MAI memorizza quel token nella memoria del browser:cioè un cookie. Quando vengono fatte richieste, prima di fare qualsiasi cosa, controlli il token

//note, you'll want to sanitize user input, I'm just being brief
if ($_GET['token'] != $_SESSION['token']){
   //User either attempted to enter a link on their own or it's a CSRF attack
   header('HTTP/1.1 403 Forbidden');
 }else{
 //do whatever needs to be done
 }

La chiave per questo è che tutti i collegamenti sul tuo sito includeranno il token. Tuttavia, Bob non ha modo di sapere quale sia quel token perché non è memorizzato in un cookie sul browser. Se tenta di creare un collegamento a una delle tue pagine, conterrà la chiave sbagliata o non conterrà alcuna chiave e puoi negarlo. (Per essere onesti, c'è la possibilità che possa indovinare correttamente il token per un utente specifico che vede il suo codice, ma probabilmente è più probabile che prenda fuoco.)

Non è nemmeno necessario assegnare un timeout al token in quanto il token verrà cancellato alla chiusura del browser e dovrà essere rigenerato quando l'utente visita il sito.