2010-02-12 26 views
10

Để bảo vệ chống lại CSRF, bạn nên đặt một nonce vào trường ẩn trong biểu mẫu và trong cookie hoặc trong biến phiên. Nhưng nếu người dùng mở nhiều trang trong các tab khác nhau thì sao? Trong trường hợp này, mỗi tab sẽ có một biểu mẫu với một nonce duy nhất, nhưng sẽ chỉ có một nonce được lưu trữ trong biến session hoặc cookie. Hoặc nếu bạn cố gắng lưu trữ tất cả các nonces trong biến cookie/session, làm thế nào bạn sẽ xác định được cái nào thuộc về dạng nào?Bảo vệ CSRF bằng cách lưu trữ nonce trong biến Phiên và biểu mẫu

Trả lời

6

Bạn có thể lưu trữ cùng một nonce trong từng biểu mẫu. Cách dễ nhất để làm điều đó là liên kết nonce với ID phiên, để các biểu mẫu đó chỉ hoạt động trong phiên đó.

Bạn sẽ muốn gây khó khăn cho những kẻ tấn công để đánh lừa ID phiên và tạo các nonces của riêng họ. Vì vậy, một trong những cách để đi về nó là sử dụng HMAC-SHA256 (hoặc tương tự) để băm ID phiên, sử dụng một khóa mà bạn không tiếp xúc với công chúng.

(Rõ ràng nếu kẻ tấn công có thể tự nhận được ID phiên thực tế, họ có thể đã thực hiện tấn công phiên. Vì vậy, đó không phải là những gì tôi đang nói, mà là khả năng kẻ tấn công viết kịch bản (chạy trên máy tính của nạn nhân) mà bằng cách nào đó có thể lấy các session ID và sử dụng để tự động tạo ra một URL với nonce điền sẵn)


ETA:. cho dù cách tiếp cận trên là đủ ngày của riêng mình phụ thuộc vào bao lâu bạn mong đợi các phiên điển hình của bạn sẽ kéo dài. Nếu người dùng thường sử dụng các phiên lâu dài kéo dài hơn một vài giờ, bạn sẽ cần phải sử dụng một cái gì đó tinh vi hơn.

Một cách tiếp cận là tạo một nonce mới cho mỗi biểu mẫu, có chứa dấu thời gian, cũng như (trong đó hash là một số biến thể của HMAC như được mô tả ở trên, để ngăn chặn sự giả mạo, và . là chuỗi nối). Sau đó bạn xác minh nonce bởi:

  1. kiểm tra dấu thời gian để đảm bảo rằng các nonce là đủ tươi (điều này tùy thuộc vào chính sách của bạn, nhưng một vài giờ là điển hình)
  2. sau đó, tính toán băm dựa trên dấu thời gian và ID phiên và so sánh với nonce, để xác minh rằng nonce là xác thực

Nếu kiểm tra không thành công, bạn sẽ muốn hiển thị biểu mẫu mới, được điền trước bằng trình gửi của người dùng (để nếu họ mất một ngày để viết bài của họ, họ sẽ không mất tất cả công việc khó khăn của họ), cũng như một nonce tươi. Sau đó, người dùng có thể gửi lại ngay lập tức thành công.

+0

Vì vậy, bạn sẽ không tạo ra một nonce mới mỗi lần sau đó? Các nonce sẽ ở lại giống nhau trong toàn bộ phiên, và đối với một số đệ trình. – Marius

+0

@Marius: Tôi sẽ cập nhật câu trả lời của tôi để trả lời nhận xét của bạn. :-) –

+0

-1 Không kẻ tấn công nào không có id phiên, trình duyệt thực hiện. Đây không phải là một công việc cho một HMAC. – rook

2

Một số người tạo mã thông báo cho từng biểu mẫu và đó là cách tiếp cận rất an toàn. Tuy nhiên, điều này có thể phá vỡ ứng dụng của bạn và piss off người dùng. Để ngăn chặn tất cả XSRF đối với trang web của bạn, bạn chỉ cần một biến mã thông báo duy nhất trên mỗi phiên và sau đó kẻ tấn công sẽ không thể giả mạo bất kỳ yêu cầu nào trừ khi anh ta có thể tìm thấy mã thông báo 1 này. Vấn đề nhỏ với cách tiếp cận này là kẻ tấn công có thể bạo lực mã thông báo này miễn là nạn nhân đang truy cập một trang web mà kẻ tấn công điều khiển. BAO GIỜ nếu mã thông báo là khá lớn như 32 byte hoặc lâu hơn, sau đó nó sẽ mất nhiều năm để sức mạnh vũ phu, và phiên http sẽ hết hạn lâu trước đó.

+0

Người tấn công không thể yêu cầu biểu mẫu nhận mã thông báo hợp lệ? Có vẻ khá đơn giản. –

+1

@ Chris Moschini thats không làm thế nào xsrf hoạt động. Bạn đang cưỡi trên phiên của người khác không phải của riêng bạn, điều đó không có ý nghĩa. – rook

+0

Cảm ơn. Điều gì xảy ra khi máy chủ ở đằng sau proxy ngược và phiên HTTP được gia hạn cho mỗi yêu cầu? –

0

Thời gian dài bài đăng này được viết. Tôi đã triển khai trình chặn csrf mà tôi gần như chắc chắn bảo vệ tốt. Nó hoạt động với nhiều cửa sổ đang mở, nhưng tôi vẫn đang đánh giá loại bảo vệ mà nó cung cấp. Nó sử dụng phương pháp DB, tức là lưu trữ thay vì phiên tới một bảng. LƯU Ý: Tôi sử dụng MD5 trong trường hợp này như một cơ chế chống SQLI dễ

Pseudo Code:

MẪU:

token = randomstring #to be used in form hidden input 
db->insert into csrf (token, user_id) values (md5(token),md5(cookie(user_id)) 

- token sau đó được lưu giữ trong db cho đến khi nó được truy xuất từ kịch bản hành động, dưới đây:

action script:

if md5(post(token)) belongs to md5(cookie(user_id)) 
    #discard the token 
    db -> delete from csrf where token=md5(post(token)) and user_id=md5(cookie(user_id)) 
    do the rest of the stuff 
+0

Việc thêm id người dùng vào bản ghi không thực sự thêm vào bảo mật, nhưng nó cho phép xóa mã thông báo không sử dụng của người dùng khỏi db khi ngắt kết nối. –

2

Những gì bạn mô tả không phải là một nonce nữa (nonce = số được sử dụng một lần), nó chỉ là một định danh phiên. Toàn bộ quan điểm của nonce là nó chỉ hợp lệ cho một biểu mẫu đơn, do đó cung cấp bảo mật cao hơn chống lại tấn công hơn chỉ là ID phiên, nhưng với chi phí không thể có nhiều tab hoạt động song song trên trang web.

Nonces là quá mức cần thiết cho nhiều mục đích. Nếu bạn sử dụng chúng, bạn chỉ nên đặt và yêu cầu chúng trên các biểu mẫu thực hiện các thay đổi quan trọng đối với hệ thống và giáo dục người dùng rằng họ không thể mong đợi sử dụng nhiều hơn một biểu mẫu như vậy song song. Các trang không thiết lập một nonce nên cẩn thận không xóa bất kỳ nonce được lưu trữ trước đó từ phiên, để người dùng vẫn có thể sử dụng các trang không phải nonced song song với một hình thức nonced.

Các vấn đề liên quan