2013-08-08 16 views
9

Backbone.js obsługuje wysyłanie danych do serwera pod maską, więc nie ma łatwego sposobu na wstawienie tokena CSRF w polu danych. Jak mogę chronić moją witrynę przed CSRF w tej sytuacji?Jak chronić się przed CSRF podczas używania Backbone.js do publikowania danych?

W tej odpowiedzi na pytanie: https://stackoverflow.com/a/10386412/954376, sugerowana jest weryfikacja nagłówka x-Requested-By jako żądania XMLHTTPRequest. Czy to wystarczy, aby zablokować wszystkie próby CSRF?

W dokumentach Django sugeruje się dodanie tokenu CSRF do innego niestandardowego nagłówka w każdym żądaniu AJAX: https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax. Czy to konieczne?

Rozumiem, że atak wykorzystuje ukrytą formę, jestem bezpieczny, zapewniając, że żądanie pochodzi z XMLHTTPRequest. Ale czy są jakieś sztuczki ataku CSRF, które mogą wykuć nagłówek?

+0

„Jestem bezpieczny tylko o zapewnienie żądanie pochodzi z XMLHTTPRequest "- Nie można tego zagwarantować. – Quentin

Odpowiedz

4

Można użyć prefilter dodać token do wszystkich żądań:

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

może trzeba dodać dodatkowe logiki, jeśli nie zawsze wysłać token.

+0

Dzięki za odpowiedź! Więc po prostu weryfikacja nagłówka X-Requested-with nie jest dobra? Jaki atak może wykuć ten nagłówek? – NeoWang

+1

@NeoWang Te, które używają błędów w wtyczkach takich jak Flash. Nie możesz sfałszować nagłówka w normalnej sytuacji CSRF, więc nie ma błędów. Możesz uważać, że zawsze tylko wysyłanie i sprawdzanie tokena jest znacznie prostsze niż czasami sprawdzanie tokena, a czasem sprawdzanie nagłówka. – Esailija

15

Ustawienie globalne CSRF token dla wszystkich jQuery.ajax wzywa:

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

Ustawianie token tylko dla Backbone nadrzędnymi 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: Poprawiono literówkę punktów Kadam w komentarzach

+1

Poprawna pisownia klucza nagłówka to 'X-CSRFToken'. W twojej pierwszej sugestii jest dodatkowy kreska, która go łamie. – kadam

+1

@kadam poprawna pisownia klucza nagłówka zależy od serwera. Na przykład Express 3 używa 'X-CSRF-Token'. http://expressjs.com/3x/api.html#csrf – bentael

1

Oto zaktualizowana wersja, oparta na Django 1.7 (za pomocą plików cookie plugin 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