2013-08-08 33 views
9

Backbone.js xử lý dữ liệu đăng lên máy chủ dưới mui xe, do đó, không có cách nào dễ dàng để chèn mã thông báo CSRF vào tải trọng. Làm thế nào tôi có thể bảo vệ trang web của mình chống lại CSRF trong tình huống này?Làm thế nào để bảo vệ chống lại CSRF khi sử dụng Backbone.js để đăng dữ liệu?

Trong câu trả lời SO này: https://stackoverflow.com/a/10386412/954376, đề xuất là xác minh tiêu đề x-Requested-By là XMLHTTPRequest. Điều này có đủ để chặn tất cả các nỗ lực CSRF không?

Trong tài liệu Django, đề xuất là thêm mã thông báo CSRF vào tiêu đề tùy chỉnh khác trong mọi yêu cầu AJAX: https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax. Điều này có cần thiết không?

Tôi hiểu nếu cuộc tấn công sử dụng biểu mẫu ẩn, tôi an toàn bằng cách chỉ đảm bảo yêu cầu là từ XMLHTTPRequest. Nhưng có bất kỳ thủ thuật tấn công CSRF nào có thể giả mạo tiêu đề không?

+0

"Tôi an toàn bằng cách chỉ đảm bảo yêu cầu là từ XMLHTTPRequest "- Bạn không thể đảm bảo điều đó. – Quentin

Trả lời

4

Bạn có thể sử dụng một prefilter để thêm dấu hiệu cho tất cả các yêu cầu:

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

Bạn có thể cần thêm logic bổ sung nếu bạn không phải lúc nào gửi mã thông báo.

+0

Cảm ơn câu trả lời của bạn! Vì vậy, chỉ cần xác minh tiêu đề X-Requested-with là không tốt? Loại tấn công nào có thể giả mạo tiêu đề này? – NeoWang

+1

@NeoWang Những người sử dụng lỗi trong các plugin như Flash. Bạn không thể giả mạo tiêu đề trong một tình huống CSRF bình thường, vì vậy nó không có lỗi. Bạn có thể xem xét rằng luôn luôn chỉ gửi và kiểm tra mã thông báo đơn giản hơn nhiều so với đôi khi kiểm tra mã thông báo và đôi khi kiểm tra tiêu đề. – Esailija

15

Thiết lập một CSRF-dấu hiệu toàn cầu cho tất cả jQuery.ajax gọi:

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

Thiết token chỉ cho Backbone bằng cách ghi đè 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: Cố định một lỗi đánh máy Kadam điểm tại các ý kiến ​​

+1

Chính tả chính xác của khóa tiêu đề là 'X-CSRFToken'. Có dấu gạch ngang bổ sung trong đề xuất đầu tiên của bạn để phá vỡ nó. – kadam

+1

@kadam chính tả chính xác của khóa tiêu đề phụ thuộc vào máy chủ. Ví dụ, Express 3 sử dụng 'X-CSRF-Token'. http://expressjs.com/3x/api.html#csrf – bentael

0

Tôi biết đó là một câu hỏi cũ, nhưng tôi sẽ để lại một liên kết đến repo github của mô-đun AMD chỉ cho điều này:

https://github.com/kuc2477/backbone.csrf.git (từ chối trách nhiệm: Tôi là tác giả của các mô-đun)

1

Dưới đây là một phiên bản cập nhật, có trụ sở tại Django 1.7 (sử dụng cookie jQuery plugin)

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 
Các vấn đề liên quan