10/10/2018, 11:11
Chống flood hiệu quả khi sử dụng ajax
Ví dụ trong trường hợp đăng ký thành viên.
Mình có trang index.php cho phép đăng ký thành viên.
Quá trình xử lý thông tin sẽ qua javascript và truyền dữ liệu đến file post.php bằng ajax (file post.php sẽ add thông tin vào database).
Ở đây mình nghĩ đến các giải pháp:
+ đặt captcha (hơi bất tiện)
+ set session timeout
+ dùng define (ko có hiệu quả khi mà file post.php được gọi qua ajax).
Chủ yếu ở đây mình muốn hạn chế người dùng truyền dữ liệu trực tiếp đến file post.php bằng form html mà họ tạo thôi. Mong các bạn đề xuất giải pháp.
Mình có trang index.php cho phép đăng ký thành viên.
Quá trình xử lý thông tin sẽ qua javascript và truyền dữ liệu đến file post.php bằng ajax (file post.php sẽ add thông tin vào database).
Ở đây mình nghĩ đến các giải pháp:
+ đặt captcha (hơi bất tiện)
+ set session timeout
+ dùng define (ko có hiệu quả khi mà file post.php được gọi qua ajax).
Chủ yếu ở đây mình muốn hạn chế người dùng truyền dữ liệu trực tiếp đến file post.php bằng form html mà họ tạo thôi. Mong các bạn đề xuất giải pháp.
Bài liên quan
để chống flood do thành viên đã đăng ký thì khi họ post 1 bài, mốc thời gian (timestamp) của bài viết này sẽ được lưu lại trong csdl. Khi họ post 1 bài nữa, trc khi cho đăng script sẽ kiểm tra xem khoảng cách thời gian giữa 2 bài viết đã đủ dài chưa (bằng cách so sánh giữa mốc thời gian hiện tại & mốc thời gian của bài viết cuối của họ). Nếu đủ dài rồi mới cho đăng bài.
ko thể áp dụng cách này cho thành viên chưa đăng ký, vì không có bất kỳ cách nào chắc chắn để hạn chế một bot post bài ngoài việc yêu cầu nó xác nhận rằng nó là người chứ ko phải máy. Chẳng hạn có thể theo dõi các mốc thời gian post bài của 1 thành viên chưa đăng ký qua IP của họ để áp dụng giải pháp hạn chế như trên, nhưng bot có thể đổi IP để post bài.
captcha có 3 yếu tố quan trọng:
- dãy số phải đủ dài (tối thiểu nên để 4 ký tự) để bot ko thể brute force đc hoặc thời gian để brute force thành công 1 mã sẽ rất lâu (do cả network). Đúng ra cũng ko gọi là brute force đc vì khi bot nhập sai 1 captcha thì 1 captcha mới nên được sinh ra - sẽ tránh đc việc bot thử 1 dãy các ký tự có thể xuất hiện trong captcha để tìm ra kết hợp đúng.
- dãy số không được sử dụng những cách viết thông thường, dễ đọc (phải làm chúng uốn éo, thêm màu nền lòe loẹt cho khó nhìn...), và đặc biệt các ký tự ko đc theo 1 pattern nhất định (chẳng hạn chữ số 1 thì lúc phải đổ về bên phải, lúc phải đổ về bên trái..). Điều này nhằm tránh các phần mềm nhận dạng ký tự (OCR) đọc đc captcha
- dãy số captcha ko đc xuất hiện trên trang web ở bất cứ đâu (url hay nội dung html). Ngày trc tôi đã gặp trường hợp khi sửa code ng khác họ để nội dung captcha vào một hidden input field, để khi ng dùng gửi form thì so sánh captcha họ nhập với giá trị của hidden input đó).
nếu ko muốn dùng captcha có thể đặt câu hỏi ngẫu nhiên và yêu cầu ng dùng trả lời với đáp án nhất định. Chú ý: số lượng câu hỏi phải rất nhiều để tránh bot đoán mò ra đáp án (nếu số câu hỏi ít thì cũng giống như captcha có ít ký tự)
Ví dụ như tạo form html và gửi trực tiếp đến link: http://www.ddth.com/newreply.php?do=...y&t=553542 thì bị chặn lại.
Còn việc bạn hỏi chỉ đơn giản là làm sao phân biệt giữa 1 POST request gửi bởi javascript (ajax) & 1 request gửi bởi 1 html form. Google $_SERVER['HTTP_X_REQUESTED_WITH'] để tìm hiểu thêm. Tuy nhiên để chắc chắn hơn, vì ko phải javascript framework nào cũng gửi "X-Requested-With" header trong các ajax request của mình, bạn có thể thêm vào các ajax request một biến để php script có thể phân biệt giữa request = ajax & request thông thường. vd: http://www.ddth.com/newreply.php?do=...y&t=553542&ajax=1
Thường là dùng define tại index.php rồi check defined tại post.php, nhưng ở đây gọi post.php qua ajax nên ko check được defined.
Dùng $_SERVER['HTTP_X_REQUESTED_WITH']so sánh với 'XMLHttpRequest' thì có vẻ ok, nhưng mình chưa hiểu là trong trường hợp hợp nào thì sẽ không đúng.
Bạn có nói "Tuy nhiên để chắc chắn hơn, vì ko phải javascript framework nào cũng gửi "X-Requested-With" header trong các ajax request của mình, bạn có thể thêm vào các ajax request một biến để php script có thể phân biệt giữa request = ajax & request thông thường", mình không hiểu lắm, vì truy vấn của mình là qua ajax rồi mà. Mong giải thích thêm.
Giải pháp chống flood ở đây mình muốn nhắc đến chính là chặn không cho gửi dữ liệu từ 1 form ngoài server ý, còn trong server thì mình có thể kiểm soát đc.