it-swarm-vi.com

Cách chính xác để triển khai mã thông báo chống CSRF là gì?

Tôi hoàn toàn biết về CSRF và đã thực hiện một số hình thức an toàn, nhưng tôi chưa bao giờ hài lòng với kết quả này.

Tôi đã tạo mã thông báo dưới dạng md5 tên người dùng, thông tin biểu mẫu và salt và lưu trữ nó trong một phiên. Điều này có vấn đề với trình duyệt theo thẻ (có thể được khắc phục bằng cách giữ một mảng băm hoạt động) và với thời gian. Tôi muốn băm của tôi chỉ hoạt động ví dụ. 10 phút, nhưng làm cách nào để đặt biến liên quan đến thời gian trong hàm băm?

Ai đó có thể chỉ cho tôi một tài nguyên tốt mô tả cách bảo mật CSRF đúng cách không?

34
naugtur

Cách tốt nhất để xây dựng bảo vệ CSRF đúng cách:

Đừng.

Hầu hết các khung phổ biến đều có bảo vệ này đã được tích hợp sẵn (ASP.NET, Struts, Ruby tôi nghĩ) hoặc có các thư viện hiện đã được hiệu đính. (Ví dụ CSRFGuard của OWASP ).

Một tùy chọn khác, tùy thuộc vào ngữ cảnh của bạn, là để thực thi xác nhận lại người dùng, nhưng chỉ cho các hoạt động cụ thể, nhạy cảm.


Theo nhận xét của bạn, nếu bạn cần tự thực hiện việc này, giải pháp của bạn không quá tệ, nhưng tôi sẽ đơn giản hóa nó.
[.___ Trong mỗi biểu mẫu, bạn bao gồm số nonce trong trường biểu mẫu ẩn và so sánh giá trị đó khi biểu mẫu được đăng.
[.___.] Nếu mã thông báo biểu mẫu khớp, bạn rõ ràng. Nếu không, bạn có thể chấp nhận, ví dụ: mã thông báo trước đó cũng vậy, để xử lý các trường hợp Edge.

Mặc dù tôi phải nói rằng tôi đã thấy quá nhiều lần thất bại trong việc thực hiện điều này một mình, để thực sự đề xuất con đường này. Bạn vẫn nên tìm một gói tối thiểu để làm điều này cho bạn.

25
AviD

Có một lời giải thích hay về OWASP: Tờ cheat phòng chống CSRF của OWASP

Nói tóm lại, họ nói rằng có hai cách:

  1. Thêm mã thông báo ngẫu nhiên cho mỗi phiên người dùng. Chỉ khi mã thông báo này có mặt và chính xác thì các thay đổi sẽ được áp dụng, nếu không yêu cầu sẽ bị từ chối. Điều quan trọng là mã thông báo chỉ được gửi với yêu cầu POST, vì các yêu cầu GET có thể rò rỉ mã thông báo đến các nơi khác nhau (lịch sử trình duyệt, tệp nhật ký, v.v.).

    Cũng có thể tạo mã thông báo cho mỗi yêu cầu, nhưng điều này dẫn đến các vấn đề về khả năng sử dụng. Ví dụ, nút quay lại sẽ không hoạt động đúng nữa. Nhưng tất nhiên an ninh sẽ được tăng lên.

    Ngoài ra, hãy đảm bảo (để tăng cường bảo mật hơn nữa) rằng mã thông báo chỉ được gửi qua TLS, vì vậy sẽ không có bất kỳ người đàn ông nào gặp vấn đề ở giữa.

  2. Tùy chọn khác là sử dụng một số loại thử thách - phản hồi (ví dụ CAPTCHA hoặc mã thông báo một lần).

OWASP-Page cũng liệt kê một số biện pháp không hoạt động. đó là

  • Sử dụng (bí mật) cookie
  • Không sử dụng các yêu cầu GET
  • Giao dịch nhiều bước
  • Viết lại URL
27
Andreas Arnold

Ngoài câu trả lời @Andreas Arnold còn có một cách khác. Tôi đã thực hiện Encrypted Token Pattern từ OWasp.

Ngoài việc ngăn chặn các cuộc tấn công csrf, nó còn có thêm lợi thế là triển khai bảo mật đối tượng.

Chỉ những người được ủy quyền sửa đổi các đối tượng, có thể làm như vậy. Những người khác sẽ không có văn bản hoặc khóa mật mã chính xác/hợp lệ. Tôi thường mã hóa sessionId, timestamp, userId và/hoặc recordId.

timestamp ngăn chặn phát lại. sessionid chỉ cách ly các thay đổi đối với phiên này userId chỉ cách ly các thay đổi đối với người dùng này. Nếu bạn bao gồm recordId, thì với chi phí xử lý thêm, bạn sẽ có được bảo mật hơn.

3
Nasir