Kaito KID
VIP Members
-
02/07/2013
-
23
-
41 bài viết
CSRF – Khái niệm, kịch bản khai thác và cách phòng chống (phần 2).
[h=1]3. Cách phòng chống[/h][h=2]3.1. Các phương pháp không hiệu quả[/h]Sử dụng secret cookie
Nên nhớ rằng mọi cookie, dù là bí mật đi chăng nữa, cũng đều được submit mỗi khi người dùng request đến server. Tất cả các token dùng để xác thực sẽ được submit bất kể người dùng cuối có bị lừa hay không. Hơn nữa, session ID chỉ dùng để liên kết request với một session object cụ thể mà không xác nhận được rằng request đó có phải do người dùng muốn thực hiện hay không.
Chỉ chấp nhận phương thức POST
Các ứng dụng có thể được triển khai với việc chỉ chấp nhận phương thức POST để thực thi nghiệp vụ của mình. Sai lầm ở đây là việc cho rằng kẻ tấn công không thể xây dựng được các đường dẫn với phương thức POST, và khi đó không thể khai thác được CSRF. Điều này hoàn toàn không đúng. Có rất nhiều cách để lừa người dùng request lên server với phương thức POST, chẳng hạn một form đơn giản chứa trong website của kẻ tấn công, và có thêm các giá trị bị ẩn đi. Form này có thể được kích hoạt tự động bằng Javascript mỗi khi người dùng truy cập vào website của kẻ tấn công. Vấn đề còn lại chỉ là lừa người dùng vào website này mà thôi. Điều này có thể thực hiện bằng cách post các đường dẫn trên Facebook, Gmail,…
Giao dịch nhiều bước
Giao dịch nhiều bước không phải là cách tốt để chống CSRF. Kẻ tấn công có thể dự đoán hoặc suy luận ra các bước đấy, từ đó khai thác CSRF.
[h=2]3.2. Sử dụng Synchronizer Token[/h]Phương pháp phổ biến nhất để chống CSRF là sử dụng synchronizer token (đọc thêm về synchronizer token: http://www.corej2eepatterns.com/Design/PresoDesign.htm). Trong phương pháp này, ứng với mỗi phiên làm việc của người dùng sẽ có một token được sinh ra ngẫu nhiên. Token này có hiệu lực trong suốt phiên làm việc và bị hủy bỏ khi người dùng đăng xuất.
Cách làm này được mô tả ngắn gọn như sau:
Sau khi người dùng đăng nhập thành công vào website, ứng dụng web sẽ sử dụng một thuật toán sinh ngẫu nhiên token. Token này được điền vào một hidden input, với một tên chung, chẳng hạn CSRFToken, và được gán vào tất cả các form. Mỗi khi người dùng submit nội dung của các form này, giá trị của token sẽ được POST kèm theo lên server. Để an toàn, thuật toán được chọn phải sinh ra chuỗi token khó đoán, càng khó đoán càng tốt.
Ví dụ về một form có chứa CSRFToken:
Khi người dùng gửi request lên server, server sẽ kiểm tra xem giá trị CSRFToken có khớp với giá trị của token đang được lưu tạm trên server hay không. Nếu không khớp thì request sẽ bị bỏ qua.
Lưu ý, chỉ gửi giá trị của CSRFToken lên server theo phương thức POST. Nếu chúng ta sử dụng phương thức GET thì coi như việc làm này không có hiệu quả.
[h=2]3.3. Các cách phòng chống không sử dụng Synchronizer Token[/h][h=3]3.3.1. Kiểm tra Referer Header[/h]Kiểm tra Referer Header cũng là một cách để phòng chống CSRF. Mỗi lần có request đến server, server sẽ kiểm tra trường Referer trong header, xem request này bắt nguồn từ đâu. Nếu nó bắt nguồn từ một domain khác thì bỏ qua.
Tuy nhiên, kiểm tra Referer Header không phải là phương pháp tốt để phòng chống CSRF. Ví dụ, lỗi open redirect có thể được sử dụng để bypass cơ chế kiểm tra referer, và một số trình duyệt tự động loại bỏ trường referer như là cách để bảo vệ dữ liệu.
Nói chung, cách kiểm tra này loại bỏ được CSRF trong một số trường hợp, nhưng không loại bỏ được hoàn toàn CSRF.
[h=3]3.3.2. Challenge-Response[/h]Challenge-Response là một phương pháp phòng chống CSRF khác. Lập trình viên có thể sử dụng:
· CAPTCHA
· Re-authentication (yêu cầu nhập lại mật khẩu)
· One-time Token
Tuy Challenge-Response rất hữu hiệu trong phòng chống CSRF, nhưng nó lại gây ảnh hưởng đến trải nghiệm người dùng, tạo cảm giác không thoải mái. Chỉ nên áp dụng phương pháp này đối với các hệ thống yêu cầu bảo mật ở mức cao.
4. Tài liệu tham khảo
https://www.owasp.org/index.php/Cross-Site_Request_Forgery
https://www.owasp.org/index.php/Reviewing_code_for_Cross-Site_Request_Forgery_issues
https://www.owasp.org/index.php/Testing_for_CSRF_(OTG-SESS-005)
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
Nên nhớ rằng mọi cookie, dù là bí mật đi chăng nữa, cũng đều được submit mỗi khi người dùng request đến server. Tất cả các token dùng để xác thực sẽ được submit bất kể người dùng cuối có bị lừa hay không. Hơn nữa, session ID chỉ dùng để liên kết request với một session object cụ thể mà không xác nhận được rằng request đó có phải do người dùng muốn thực hiện hay không.
Chỉ chấp nhận phương thức POST
Các ứng dụng có thể được triển khai với việc chỉ chấp nhận phương thức POST để thực thi nghiệp vụ của mình. Sai lầm ở đây là việc cho rằng kẻ tấn công không thể xây dựng được các đường dẫn với phương thức POST, và khi đó không thể khai thác được CSRF. Điều này hoàn toàn không đúng. Có rất nhiều cách để lừa người dùng request lên server với phương thức POST, chẳng hạn một form đơn giản chứa trong website của kẻ tấn công, và có thêm các giá trị bị ẩn đi. Form này có thể được kích hoạt tự động bằng Javascript mỗi khi người dùng truy cập vào website của kẻ tấn công. Vấn đề còn lại chỉ là lừa người dùng vào website này mà thôi. Điều này có thể thực hiện bằng cách post các đường dẫn trên Facebook, Gmail,…
Giao dịch nhiều bước
Giao dịch nhiều bước không phải là cách tốt để chống CSRF. Kẻ tấn công có thể dự đoán hoặc suy luận ra các bước đấy, từ đó khai thác CSRF.
[h=2]3.2. Sử dụng Synchronizer Token[/h]Phương pháp phổ biến nhất để chống CSRF là sử dụng synchronizer token (đọc thêm về synchronizer token: http://www.corej2eepatterns.com/Design/PresoDesign.htm). Trong phương pháp này, ứng với mỗi phiên làm việc của người dùng sẽ có một token được sinh ra ngẫu nhiên. Token này có hiệu lực trong suốt phiên làm việc và bị hủy bỏ khi người dùng đăng xuất.
Cách làm này được mô tả ngắn gọn như sau:
Sau khi người dùng đăng nhập thành công vào website, ứng dụng web sẽ sử dụng một thuật toán sinh ngẫu nhiên token. Token này được điền vào một hidden input, với một tên chung, chẳng hạn CSRFToken, và được gán vào tất cả các form. Mỗi khi người dùng submit nội dung của các form này, giá trị của token sẽ được POST kèm theo lên server. Để an toàn, thuật toán được chọn phải sinh ra chuỗi token khó đoán, càng khó đoán càng tốt.
Ví dụ về một form có chứa CSRFToken:
Mã:
…
Khi người dùng gửi request lên server, server sẽ kiểm tra xem giá trị CSRFToken có khớp với giá trị của token đang được lưu tạm trên server hay không. Nếu không khớp thì request sẽ bị bỏ qua.
Lưu ý, chỉ gửi giá trị của CSRFToken lên server theo phương thức POST. Nếu chúng ta sử dụng phương thức GET thì coi như việc làm này không có hiệu quả.
[h=2]3.3. Các cách phòng chống không sử dụng Synchronizer Token[/h][h=3]3.3.1. Kiểm tra Referer Header[/h]Kiểm tra Referer Header cũng là một cách để phòng chống CSRF. Mỗi lần có request đến server, server sẽ kiểm tra trường Referer trong header, xem request này bắt nguồn từ đâu. Nếu nó bắt nguồn từ một domain khác thì bỏ qua.
Tuy nhiên, kiểm tra Referer Header không phải là phương pháp tốt để phòng chống CSRF. Ví dụ, lỗi open redirect có thể được sử dụng để bypass cơ chế kiểm tra referer, và một số trình duyệt tự động loại bỏ trường referer như là cách để bảo vệ dữ liệu.
Nói chung, cách kiểm tra này loại bỏ được CSRF trong một số trường hợp, nhưng không loại bỏ được hoàn toàn CSRF.
[h=3]3.3.2. Challenge-Response[/h]Challenge-Response là một phương pháp phòng chống CSRF khác. Lập trình viên có thể sử dụng:
· CAPTCHA
· Re-authentication (yêu cầu nhập lại mật khẩu)
· One-time Token
Tuy Challenge-Response rất hữu hiệu trong phòng chống CSRF, nhưng nó lại gây ảnh hưởng đến trải nghiệm người dùng, tạo cảm giác không thoải mái. Chỉ nên áp dụng phương pháp này đối với các hệ thống yêu cầu bảo mật ở mức cao.
4. Tài liệu tham khảo
https://www.owasp.org/index.php/Cross-Site_Request_Forgery
https://www.owasp.org/index.php/Reviewing_code_for_Cross-Site_Request_Forgery_issues
https://www.owasp.org/index.php/Testing_for_CSRF_(OTG-SESS-005)
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet