web-dev-qa-db-ja.com

ブルートフォース攻撃を防ぐ最良の方法は何ですか?

ログインページがあります。もちろん、ブルートフォース攻撃を防ぎ、ユーザーがログインする際の遅延を減らしたいと思っています。

現在、ログインするにはユーザー名とパスワードを入力します。

reCAPTCHA の実装を検討しています。ただし、ログインに3回失敗すると表示されます。

私の質問は:

  1. その試みは何に基づいていますか。 IPアドレス?常に非表示にすることができます...ユーザー名?存在しないユーザーを試している場合はどうなりますか?

  2. 失敗したログイン試行をカウントする最良の方法は何でしょうか?

29
lecardo

セッションはCookieに依存しているため、信頼できません。CAPTCHAは定期的に破損します[ReCAPTCHAを含む]。唯一の信頼できる方法は一見簡単です:質問をします。コンピューターは驚くほど何らかの理由でそれらを解決するのが得意であるため、数学の質問を使用しないでください。偉大な古いスタンバイは次のようなものです:

  • このページ の6番目の段落の4番目の単語は何ですか?
  • このサイトの著者の名前は何ですか? [ヒント]

これは実装するのがばかげて簡単で、マシンが解決するのは非常に困難です。

強制的には、ユーザーテーブルに2つのフィールド、 'first_failed_login' [INTEGER unix timestampまたはDATETIME]と 'failed_login_count'を追加してみてください。 [INTEGER]

<?php
$bad_login_limit = 3;
$lockout_time = 600;

$first_failed_login, failed_login_count; // retrieve from DB

if(
    ($failed_login_count >= $bad_login_limit)
    &&
    (time() - $first_failed_login < $lockout_time)
) {
  echo "You are currently locked out.";
  exit; // or return, or whatever.
} else if( /* login is invalid */ ) {
  if( time() - $first_failed_login > $lockout_time ) {
    // first unsuccessful login since $lockout_time on the last one expired
    $first_failed_login = time(); // commit to DB
    $failed_login_count = 1; // commit to db
  } else {
    $failed_login_count++; // commit to db.
  }
  exit; // or return, or whatever.
} else {
  // user is not currently locked out, and the login is valid.
  // do stuff
}

これにより、ログインシステムはユーザーごとに10分ごとに3回のログイン試行のみを認識します。

47
Sammitch

セッションやCookieに依存しないでください。これらはクライアントを信頼するため、クライアントを決して信頼しないでください。 PHPでブルートフォース攻撃から保護するクラスを作成しました。

https://github.com/ejfrancis/BruteForceBlocker

サイト全体の失敗したログインをすべてdbテーブルに記録し、過去10分間(または選択した時間枠)で失敗したログインの数が設定された制限を超えている場合、時間遅延および/またはキャプチャ要件を強制します再度ログインする前に。

例:

 //build throttle settings array. (# recent failed logins => response).

 $throttle_settings = [

         50 => 2,            //delay in seconds
         150 => 4,           //delay in seconds
         300 => 'captcha'    //captcha 
];


 $BFBresponse = BruteForceBlocker::getLoginStatus($throttle_settings); 

//$throttle_settings is an optional parameter. if it's not included,the default settings array in BruteForceBlocker.php will be used

 switch ($BFBresponse['status']){

    case 'safe':
         //safe to login
         break;
     case 'error':
         //error occured. get message
         $error_message = $BFBresponse['message'];
         break;
     case 'delay':
         //time delay required before next login
         $remaining_delay_in_seconds = $BFBresponse['message'];
         break;
     case 'captcha':
         //captcha required
         break;

 }
3
ejfrancis

実際のブラウザを使用していることを確認してください。たぶん厄介なJavaランダム関数名または何かでスクリプトがチャレンジする場合、実際のブラウザをリモート制御しない限り(これは珍しいことではありません)、js/cssを評価しない限り、スクレーパースクリプトで正しく。

このトピックをさらに読み、python mechanizeまたは他の有名なスクレーパーツールに対してソリューションをテストすることをお勧めします。

しかし、1つは確かです。自動攻撃に対する本当の解決策はありません。

2
enthus1ast