2013-08-08 5 views
9

Backbone.js gestisce la registrazione dei dati sul server, quindi non esiste un modo semplice per inserire un token CSRF nel payload. Come posso proteggere il mio sito contro CSRF in questa situazione?Come proteggere contro CSRF quando si utilizza Backbone.js per inviare dati?

In questa risposta SO: https://stackoverflow.com/a/10386412/954376, il suggerimento è di verificare che l'intestazione x-Requested-By sia XMLHTTPRequest. Basta questo per bloccare tutti i tentativi CSRF?

In Django docs, il suggerimento è di aggiungere un token CSRF in un'altra intestazione personalizzata in ogni richiesta AJAX: https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax. È necessario?

Capisco se l'attacco utilizza la forma nascosta, sono sicuro semplicemente assicurandomi che la richiesta provenga da XMLHTTPRequest. Ma ci sono trucchi di attacco CSRF che possono forgiare l'intestazione?

+0

"Sono al sicuro da solo assicurando la richiesta proviene da XMLHTTPRequest "- Non è possibile garantirlo. – Quentin

risposta

4

È possibile utilizzare un prefilter per aggiungere il token a tutte le richieste:

$.ajaxPrefilter(function(opts) { 
    if (opts.data) { 
     opts.data += "&"; 
    } 
    opts.data += "csrfToken=" + token; 
}); 

Potrebbe essere necessario aggiungere la logica aggiuntiva se non sempre inviare il token.

+0

Grazie per la tua risposta! Quindi verificare l'intestazione X-Requested-with non va bene? Che tipo di attacco può forgiare questa intestazione? – NeoWang

+1

@NeoWang Coloro che usano bug in plugin come Flash. Non puoi falsificare l'intestazione in una normale situazione CSRF, quindi va bene senza bug. Potresti considerare che inviare e controllare token è molto più semplice che a volte controllando token e talvolta controllando l'intestazione. – Esailija

15

Impostazione di una CSRF token globale per tutte le chiamate jQuery.ajax:

$(function(){ 
    $.ajaxSetup({ 
    headers: {'X-CSRFToken': CSRF_TOKEN} 
    }); 
}) 

Impostazione il token solo per Backbone sovrascrivendo Backbone.sync:

var oldSync = Backbone.sync; 
Backbone.sync = function(method, model, options){ 
    options.beforeSend = function(xhr){ 
    xhr.setRequestHeader('X-CSRFToken', CSRF_TOKEN); 
    }; 
    return oldSync(method, model, options); 
}; 

EDIT: Corretto un errore di battitura punti Kadam at in comments

+1

L'ortografia corretta della chiave di intestazione è 'X-CSRFToken'. C'è un trattino in più nel tuo primo suggerimento che lo spezza. – kadam

+1

@kadam l'ortografia corretta della chiave di intestazione dipende dal server. Ad esempio, Express 3 utilizza 'X-CSRF-Token'. http://expressjs.com/3x/api.html#csrf – bentael

1

Ecco una versione aggiornata, con sede a Django 1.7 (usando il plugin cookie di jQuery)

oldSync = Backbone.sync 
Backbone.sync = (method, model, options) -> 

    csrfSafeMethod = (method) -> 
     # these HTTP methods do not require CSRF protection 
     /^(GET|HEAD|OPTIONS|TRACE)$/.test method 

    options.beforeSend = (xhr, settings) -> 
     if !csrfSafeMethod(settings.type) and [email protected] 
      xhr.setRequestHeader 'X-CSRFToken', $.cookie('csrftoken') 
     return 
    oldSync method, model, options 
Problemi correlati