2012-04-13 10 views
5

Sono abbastanza nuovo per la sicurezza Web. Mi chiedevo quale sarebbe stato il modo corretto di utilizzare i token su richieste e moduli Ajax senza pulsanti di invio (ad esempio aggiornamenti di stato) per proteggere CSRF di nuovo. Qualcuno potrebbe mostrarmi un esempio di codice? So come farlo correttamente per i moduli con un pulsante di invio. Anche nella mia cartella ajax ho un .htaccess con il seguente:protezione contro CSRF su richieste Ajax e moduli senza pulsanti di invio

SetEnvIfNoCase X-Requested-With XMLHttpRequest ajax 
Order Deny,Allow 
Deny from all 
Allow from env=ajax 

È sufficiente sicurezza per le richieste Ajax, o devo anche implementare token di sicurezza per le richieste Ajax?

risposta

8

Tutto ciò che devi fare è generare un segreto (token) al caricamento della pagina. Mettilo sulla pagina e in sessione. Tipicamente lo metto sotto forma di campo nascosto se posso, o se fa parte di una pagina molto più grande ajaxy, lo inserirò in un attributo value su un elemento correlato come il div che avvolge l'intera pagina. Altri aggiungeranno un tag script con una variabile impostata sul segreto.

Quindi, ogni volta che si effettua una chiamata AJAX o si invia il modulo, si include un campo per il segreto. (La risposta di Cheekysoft va più nel dettaglio su come fare questo con JS non elaborato, può essere fatto grosso modo lo stesso con jQuery o qualsiasi altro framework che potresti usare.) Abbinalo al valore della sessione sul back-end per assicurarti che siano ancora lo stesso (venuto dalla stessa fonte), e tu sei buono.

Se si desidera aumentare la sicurezza, rigenerare il segreto su ogni richiesta e restituire il nuovo segreto insieme ai dati richiesti. Tutte le richieste Ajax sostituiscono quell'attributo di campo o valore nascosto con il nuovo valore. Ciò non funziona in modo corretto se si eseguono molte richieste o richieste simultanee. In realtà, generarne uno ogni volta che viene caricata l'intera pagina dovrebbe essere sufficiente se lo fai su HTTPS, che dovresti essere.

Se non lo fai su HTTPS, non importa, qualcuno seduto in un internet cafè/starbucks può semplicemente rubare la sessione e ricaricare la pagina.

Se si sta andando a fare questo molto, vale la pena controllare jQuery e various plugins che ti aiuteranno a fare la protezione CSRF per te. Also, my way isn't the only way.

+1

Grazie per la risposta. Se lo invio come intestazione della richiesta come per uno dei tuoi collegamenti: 'var csrf_token = ''; $ ("corpo"). Bind ("ajaxSend", la funzione (olmo, XHR, s) { \t se (s.type == "POST") { xhr.setRequestHeader ('X-CSRF-token' , csrf_token); } }); ' Come verifico il lato ajax? dovrei ritirare il token usando una richiesta di posta? – Anonymous

+0

@Anonimo, dipenderà dalla tua lingua preferita. Sembra PHP, quindi controllerei qualcosa come [getallheaders] (http://php.net/manual/en/function.getallheaders.php) – DampeS8N

+0

Ho capito come controllarlo: 'if ($ _ SERVER ['HTTP_X_CSRF_TOKEN'] == $ _SESSION ['ajaxtoken_value']) {' grazie. l'unico problema è che la richiesta è su http. come modifico le mie impostazioni in modo che la richiesta venga eseguita su https? – Anonymous

2

Se il tuo XHR è una richiesta GET, includere il token come parametro URL e fare in modo che lo script PHP lo legga da $_GET[]. Se il tuo XHR è un POST, inserisci il token nei dati POST e fallo leggere allo script PHP da $_POST[].

richiesta GET

var token = getElementById('myHiddenField').value; 
var xhr = new XMLHttpRequest(); 
xhr.open('GET', 'server.php?token=' + token); 
xhr.send(null); 

richiesta POST

var token = getElementById('myHiddenField').value; 
var xhr = new XMLHttpRequest(); 
xhr.open('POST', 'server.php', true); 
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
xhr.onreadystatechange = function() { 
    if (xhreq.readystate != 4) { return; } 
    // do client side stuff here 
}; 
xhr.send('token=' + token); 
+0

Probabilmente dovresti includere anche alcune note su quando e dove generare il token. E come assicurarsi di controllare lo stesso su entrambe le estremità. – DampeS8N

+0

@ DampeS8N Sentiti libero di modificarlo per completezza, ma l'OP ha detto di sentirsi a suo agio con i token CSRF nei messaggi di forma. – Cheekysoft

+0

Grazie per la risposta. Se lo invio come intestazione della richiesta: var csrf_token = ''; $ ("body"). bind ("ajaxSend", function (elm, xhr, s) {if (s.type == "POST") {xhr.setRequestHeader ('X-CSRF-Token', csrf_token);} }); Come potrei controllare sul lato Ajax? dovrei ritirare il token usando una richiesta di posta? – Anonymous