2015-11-18 13 views
6

Tôi cố gắng để ngăn chặn CSRF trong theo cách sau:Làm thế nào để ngăn chặn yêu cầu cross-site giả mạo (CSRF) một cách hiệu quả trong PHP

  1. Một $_SESSION['token'] được tạo ra ở đầu mỗi trang. Tôi đã biết rằng việc sử dụng $_COOKIES hoàn toàn sai vì chúng được gửi tự động cho mỗi yêu cầu.

  2. Trong mỗi <form>, đầu vào sau: <input type="hidden" name="t" value="<?php echo '$_SESSION['token']; ?>"> được nối thêm.

  3. Các $_SESSION['token']; được xác nhận với $_POST['t']

Bây giờ tôi có một số câu hỏi nhỏ:

  • Đây có phải là một cách tốt để ngăn chặn CSRF? Nếu không xin vui lòng giải thích.
  • Khi một trang khác được mở cũng đặt cùng một biến số $_SESSION, trang trước đó (vẫn mở) trở nên không hợp lệ, cách ngăn chặn điều này?
  • Đối với các hình thức, phương pháp này rõ ràng, nhưng cách xử lý các liên kết thông thường? Có cần thiết phải gắn thêm mã thông báo cho mỗi liên kết không?

Cảm ơn bạn rất nhiều trước.

+0

Có nhiều cách để bạn có thể củng cố thêm điều này (ví dụ:gắn mã thông báo vào các biểu mẫu riêng lẻ để chúng không thể được sử dụng lại trong một ngữ cảnh khác, đó là thư viện [anti-csrf] (https://github.com/paragonie/anti-csrf) của chúng tôi. Nhưng những gì bạn mô tả là những gì hầu hết mọi người làm. –

+0

Cảm ơn bạn @ScottArciszewski về liên kết và gợi ý, tôi muốn giữ mọi thứ trong tay mình thay vì dựa vào thư viện của bên thứ ba cho việc này nhưng đó là một ý tưởng rất hay để thậm chí hạn chế hơn nữa. –

Trả lời

5

Đây có phải là cách hay để ngăn chặn CSRF không?

Có. Điều này có nghĩa là buộc khách hàng thực hiện một GET trên biểu mẫu trước khi nó có thể thực hiện một POST cho trình xử lý biểu mẫu của bạn. Điều này ngăn cản CSRF trong trình duyệt hiện đại vì trình duyệt sẽ ngăn Javascript phía máy khách thực hiện yêu cầu XHR GET sang miền nước ngoài, do đó bên thứ ba không thể bắt chước biểu mẫu của bạn trên trang web của họ và nhận được mã thông báo hợp lệ cho việc gửi.

Khi một trang khác được mở cũng đặt cùng biến $ _SESSION, trang trước đó (vẫn mở) trở nên không hợp lệ, cách ngăn điều này?

Cho phép nhiều mã thông báo hợp lệ tại một thời điểm, giữ một loạt mã thông báo hợp lệ trong phiên. Ngoài ra, lưu trữ không có mã thông báo và thay vào đó hãy sử dụng lược đồ ký mã thông báo. Tôi đã xem xét và giải thích rằng here. Phương án 2: chỉ cần sử dụng một mã thông báo duy nhất cho toàn bộ phiên mà không có mã thông báo không hợp lệ. (tip o 'mũ để @SilverlightFox trong các ý kiến)

Đối với các hình thức này là rõ ràng, nhưng làm thế nào để xử lý các liên kết bình thường? Có cần thiết phải gắn thêm mã thông báo cho mỗi liên kết không?

số Bạn chỉ cần để bảo vệ yêu cầu POST từ có lẽ chỉ yêu cầu POST có thể thay đổi dữ liệu nhạy cảm (nháy mắt nháy mắt di chuyển di chuyển nhẹ, bạn đang gắn bó với công ước REST, phải không ?!) và yêu cầu GET XHR đã phía trình duyệt bị chặn.

+0

Cảm ơn bạn đã liên kết và dĩ nhiên tôi kiểm tra tính hợp lệ, hãy cập nhật câu hỏi của tôi để làm rõ điều đó. –

+0

Cách thuận tiện để xử lý một số mã thông báo là gì, tôi có thể sử dụng url trang không (giả sử rằng người dùng không mở cùng một trang hai lần ..) –

+0

Tôi sẽ giữ một mảng '$ token => Các giá trị $ timestamp' trong phiên; trên mỗi biểu mẫu gửi 'array_filter' mảng đó để loại bỏ các mã thông báo đã hết hạn, sau đó kiểm tra xem mã thông báo có hợp lệ với' isset ($ _ SESSION ['tokens'] [$ _ POST ['token']]) '. – deceze

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