2012-05-23 46 views
5

Tôi quan tâm đến việc bảo vệ ứng dụng web của mình bằng cách sử dụng mã thông báo csrf thế hệ. Câu hỏi của tôi là làm cách nào để gửi mã thông báo đó tới máy chủ: sử dụng tham số truy vấn hoặc tiêu đề http x-csrf-token?mã thông báo csrf sử dụng

Và những gì là sự khác biệt

Trả lời

9

Vì bạn đang sử dụng Express, bạn có thể sử dụng middleware CSRF của nó (bởi Connect): http://www.senchalabs.org/connect/csrf.html

Bạn có thể kiểm tra các nguồn nhận xét ở đây: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js

Tất cả bạn cần làm là bao gồm phần mềm trung gian đó và sau đó trong biểu mẫu POST của bạn (hoặc PUT vv bất kỳ yêu cầu nào làm biến đổi trạng thái), hãy đặt biến _csrf để có giá trị req.session._csrf.

Kiểm tra ví dụ ở đây: https://github.com/senchalabs/connect/blob/master/examples/csrf.js

CẬP NHẬT

Từ Connect 2.9.0 bạn phải sử dụng req.csrfToken() thay vì req.session._csrf

Full dụ: https://github.com/senchalabs/connect/blob/master/examples/csrf.js

Commit: https://github.com/senchalabs/connect/commit/70973b24eb1abe13b2da4f45c1edbb78c611d250

UPDATE2

Các middleware kết nối được chia thành các module khác nhau (và Repos liên kết), bạn có thể tìm thấy tất cả (bao gồm cả CSRF một) ở đây: https://github.com/senchalabs/connect#middleware

+0

Vâng Tôi biết điều này, nhưng tôi muốn biết điều gì tốt hơn để sử dụng: tiêu đề x-csrf-token hoặc trường ẩn? – Erik

+0

Như bạn thấy ở đây: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js # L69 Express kiểm tra đầu tiên cho giá trị POST, sau đó cho giá trị chuỗi truy vấn và sau đó cho tiêu đề x-csrf-token, vì vậy tốt nhất là chuyển một trường _csrf ẩn với giá trị. – alessioalex

+0

Tôi muốn sử dụng csrf-token trên ajax yêu cầu phương pháp tiếp cận nào tôi nên sử dụng sau đó? – Erik

3

Từ quan điểm của tôi, bạn nên sử dụng tham số POST csrf khi gửi biểu mẫu, trong trường bị ẩn. Đây là cách duy nhất để đi.

Nhưng đối với yêu cầu AJAX, tôi khuyên bạn nên sử dụng tiêu đề X-CSRF-Token thay thế. Chủ yếu là vì, nếu được thực hiện đúng, nó sẽ giúp bạn tiết kiệm được những rắc rối khi nhớ thêm mã thông báo cho mỗi yêu cầu POST. Hoặc, khi sử dụng các thư viện như Biểu mẫu jQuery, việc thêm các tham số POST bổ sung vào thời điểm gửi có thể trở thành hackish.

Ví dụ: nếu bạn sử dụng jQuery cho các yêu cầu AJAX của mình, nó cung cấp cho bạn a hook bạn có thể sử dụng để đặt tự động và minh bạch X-CSRF-Token trước khi yêu cầu được thực hiện. Vì vậy, rất ít sửa đổi mã phía máy khách là bắt buộc. Và bạn tăng vọt sự khiếp sợ của mã của bạn.

-

An thực hiện ví dụ, mà tôi sử dụng thành công trên hầu như tất cả các dự án của tôi, dựa trên Django của một người, sẽ là:

jQuery(document).ajaxSend(function(event, xhr, settings) { 

    function getCookie(name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie != '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
     var cookie = jQuery.trim(cookies[i]); 
     // Does this cookie string begin with the name we want? 
     if (cookie.substring(0, name.length + 1) == (name + '=')) { 
      cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
      break; 
     } 
     } 
    } 
    return cookieValue; 
    } 

    function sameOrigin(url) { 
    // url could be relative or scheme relative or absolute 
    var host = document.location.host; // host + port 
    var protocol = document.location.protocol; 
    var sr_origin = '//' + host; 
    var origin = protocol + sr_origin; 
    // Allow absolute or scheme relative URLs to same origin 
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 
      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 
      // or any other URL that isn't scheme relative or absolute i.e relative. 
      !(/^(\/\/|http:|https:).*/.test(url)); 
    } 

    function safeMethod(method) { 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) { 
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrf.token')); 
    } 
}); 

Trên server-side, bạn muốn chỉ cần đặt cookie chứa mã thông báo CSRF để khách hàng dễ dàng nhận mã thông báo. Tôi đã thay thế số app.use(express.csrf()) bằng:

app.use((function(options) { 

    var csrf = express.csrf(options); 

    return function(req, res, next) { 

    function onCsrfCalled() { 
     var token = req.session._csrf; 
     var cookie = req.cookies['csrf.token']; 

     // Define a cookie if not present 
     if(token && cookie !== token) { 
     res.cookie('csrf.token', token); 
     } 

     // Define vary header 
     res.header('Vary', 'Cookie'); 

     next(); 
    } 

    csrf(req, res, onCsrfCalled); 
    } 
})()); 
Các vấn đề liên quan