2009-05-20 62 views
6

Tôi đang làm việc trên một trang web khá lớn được xây dựng bằng PHP có khả năng sẽ có nhiều người dùng. Tôi đang tìm cách bảo vệ màn hình đăng nhập khỏi các lần thử tự động. Tôi đã bao gồm một kiểm tra CAPTCHA trên mẫu đăng ký, nhưng vẫn muốn làm vững chắc trang web hơn.Làm thế nào để trì hoãn nỗ lực đăng nhập sau quá nhiều lần thử (PHP)

Đã có câu hỏi tương tự trên StackOverflow mà tôi biết, và tôi biết tôi có khả năng thực hiện điều này bản thân mình từ đầu (lưu trữ nỗ lực đăng nhập và thời gian của họ trong db), nhưng tôi không thích mà đường dẫn:

  • Về mặt khái niệm, tôi nghĩ loại logic này thuộc về cấp độ máy chủ/cơ sở hạ tầng web, không phải cấp ứng dụng. Tôi không thích có logic và phức tạp này trong đơn đăng ký của tôi
  • Tôi lo lắng về hiệu suất, đặc biệt là ở cấp cơ sở dữ liệu.
  • tôi là lười biếng, theo một cách tốt, bởi không muốn xây dựng một tiện ích chung như thế này từ đầu

Bất kỳ lời khuyên được đánh giá cao, tôi nghĩ rằng tôi đang đặc biệt là tìm kiếm một số loại module Apache có thể làm điều này. Nền tảng của tôi là PHP5 (sử dụng CodeIgniter), Apache2, MySQL 5.

Trả lời

16

cập nhật: không sử dụng chế độ ngủ() để hạn chế tốc độ! điều này không có ý nghĩa gì cả. tôi không có một giải pháp tốt hơn trên tay.


một khởi đầu tốt sẽ là chỉ sleep(1); sau lần đăng nhập không thành công - dễ triển khai, gần như không có lỗi.

1 giây không nhiều đối với con người (đặc biệt là vì nỗ lực đăng nhập của con người không xảy ra thường xuyên), nhưng 1 giây/thử sức mạnh vũ phu ... sloooow! tấn công từ điển có thể là một vấn đề khác, nhưng nó nằm trong cùng một miền.

nếu kẻ tấn công bắt đầu quá có thể kết nối để phá vỡ điều này, bạn đối phó với một loại tấn công DOS. vấn đề được giải quyết (nhưng bây giờ bạn đã có một vấn đề khác).

một số công cụ bạn nên xem xét:

  • nếu bạn khóa các tài khoản Chỉ duy nhất trên cơ sở mỗi IP, có thể có vấn đề với mạng riêng.
  • nếu bạn khóa các tài khoản Chỉ duy nhất trên cơ sở tên truy cập, tấn công từ chối dịch vụ tấn công agains tên người dùng được biết sẽ có thể
  • khóa trên cơ sở IP/tên người dùng (trong đó username là một trong những tấn công) có thể làm việc tốt hơn

đề xuất của tôi: khóa hoàn toàn không được mong muốn (DOS), do đó, một lựa chọn tốt hơn là: đếm số lần đăng nhập cho một tên người dùng nhất định từ một IP duy nhất. bạn có thể làm điều này với một bảng đơn giản failed_logins: IP/username/failed_attempts

nếu thông tin đăng nhập thất bại, wait(failed_attempts); giây. mỗi xx phút, chạy tập lệnh cron giảm failed_logins:failed_attempts một.

xin lỗi, tôi không thể cung cấp giải pháp đã được tạo trước, nhưng điều này không đáng kể để thực hiện.

okay, được thôi.đây là mã giả:

<?php 
$login_success = tryToLogIn($username, $password); 

if (!$login_success) { 
    // some kind of unique hash 
    $ipusr = getUserIP() . $username; 

    DB:update('INSERT INTO failed_logins (ip_usr, failed_attempts) VALUES (:ipusr, 1) ON DUPLICATE KEY UPDATE failed_logins SET failed_attempts = failed_attempts+1 WHERE ip_usr=:ipusr', array((':ipusr' => $ipusr)); 

    $failed_attempts = DB:selectCell('SELECT failed_attempts WHERE ip_usr=:ipusr', array(':ipusr' => $ipusr)); 

    sleep($failed_attempts); 
    redirect('/login', array('errorMessage' => 'login-fail! ur doin it rong!')); 
} 
?> 

từ chối trách nhiệm: này có thể không làm việc trong khu vực nhất định. điều cuối cùng tôi nghe là ở châu Á có cả một quốc gia NAT (cũng vậy, tất cả đều biết kung-fu).

+0

giải pháp tốt và đơn giản Tôi đồng ý, nhưng nó vẫn yêu cầu tương tác cơ sở dữ liệu. Điều gì xảy ra nếu tôi chỉ cần thêm độ trễ 1 giây giữa phát hiện đăng nhập không thành công và hiển thị lại màn hình đăng nhập? Điều này sẽ buộc cả bot và con người phải chờ đợi sự chậm trễ. Đối với một con người nó không phải là nhiều, và ít người sẽ làm một đăng nhập sai, trong khi cho một bot nó là khá dài. Bạn nghĩ sao? – Ferdy

+0

không thực sự hữu ích, vì tôi có thể thực hiện N yêu cầu đồng thời. khối thứ hai xảy ra trên cơ sở theo yêu cầu, do đó, N yêu cầu đồng thời kết thúc sau một chút hơn 1 giây (do máy chủ có thể xử lý tải). vì vậy về nguyên tắc, tôi có thể khởi chạy 10.000 yêu cầu và yêu cầu họ hoàn thành sau một vài giây, bởi vì chúng không nối tiếp. – stefs

+0

cũng có, có> 80.000 giây mỗi ngày. 80.000 không phải là nhiều cho sức mạnh vũ phu, nhưng nó có thể đủ cho một cuộc tấn công từ điển. – stefs

2

Ví dụ chưa được thử nghiệm rất giả, nhưng tôi nghĩ, bạn sẽ tìm thấy ở đây ý tưởng chính).

if ($unlockTime && (time() > $unlockTime)) 
{ 
    query("UPDATE users SET login_attempts = 0, unlocktime = 0 ... "); 
} 
else 
{ 
    die ('Your account is temporary locked. Reason: too much wrong login attempts.'); 
} 
if (!$logged_in) 
{ 
    $loginAttempts++; 
    $unlocktime = 0; 
    if ($loginAttempts > MAX_LOGIN_ATTEMPTS) 
    { 
     $unlockTime = time() + LOCK_TIMEOUT; 
    } 
    query("UPDATE users SET login_attempts = $loginAttempts, unlocktime = $unlocktime ... "); 
} 

Xin lỗi vì những sai lầm - Tôi đã viết nó trong một số quảng cáo giây đã không kiểm tra ... Cùng bạn có thể làm bằng IP, bởi nickname, bởi session_id vv ...

-3

Tại sao don Bạn không chờ đợi với "cứng" và "mở rộng quy mô" ứng dụng của bạn cho đến khi bạn thực sự có vấn đề đó? Kịch bản có khả năng nhất là ứng dụng sẽ không bao giờ có "nhiều người dùng". Điều này nghe có vẻ như tối ưu hóa sớm với tôi, một cái gì đó để tránh.

  • Khi bạn bắt đầu sử dụng chương trình, hãy tăng cường đăng ký. Tôi thực sự sẽ xóa hình ảnh xác thực cho đến khi bạn bắt đầu nhận được> 1000 lần đăng ký/ngày.
  • Khi bạn gặp sự cố về hiệu suất, hãy cải thiện hiệu suất bằng cách sửa các nút cổ chai thực.
+3

Trong khi bạn có thể đúng về mặt khái niệm, bạn không biết nền tảng của dự án của tôi và không thể kết luận rằng nó sẽ không bao giờ có được những vấn đề này. Tôi xem xét các biện pháp bảo vệ tốt nhất này bất kể kích thước của trang web. Nếu tôi không bảo vệ chống lại nỗ lực đăng nhập, mật khẩu có thể bị đánh cắp. Làm thế nào là nó sớm để bảo vệ chống lại điều đó? Cũng vậy với Captchas. Tôi đang sử dụng phần mềm blog tùy chỉnh của riêng mình, rất nhiều một niche. Tôi chỉ có 300 độc giả và các bot vẫn tấn công nó bằng spam bình luận. Captcha là một điều phải có trong kinh nghiệm của tôi. – Ferdy

+2

Tại sao trẻ em ngăn kéo dao kéo? tại sao không chỉ đợi cho đến khi đứa trẻ bắt đầu chơi với dao? – Twifty

+0

Waldermort, đây là điều tốt nhất tôi đọc hôm nay. – MichaelClark

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