Каков наилучший способ предотвратить атаку грубой силы?

У меня есть страница входа в систему и, конечно же, я хочу предотвратить атаки с использованием грубой силы и вызывать меньше задержек для пользователей при входе в систему.

В настоящее время вы вводите свое имя пользователя и пароль для входа в систему.

Я рассматриваю возможность внедрения reCAPTCHA. Однако это показывает логин после 3 неудачных попыток.

Мой вопрос:

  1. На чем вы основали эту попытку. IP-адреса? Он всегда может быть скрыт... имя пользователя? Что делать, если они пытаются использовать пользователя, которого нет?

  2. Каким будет лучший способ подсчета неудачных попыток входа в систему?

Ответ 1

Сессии ненадежны, поскольку они полагаются на файлы cookie, CAPTCHA регулярно нарушаются [в том числе ReCAPTCHA]. Единственный надежный метод обманчиво прост: задайте вопрос. Не используйте математический вопрос, потому что компьютеры на удивление умело решают их по какой-то причине. Великие старые standbys - это такие вещи, как:

Это глупо - легко реализовать и очень сложно решить проблему.

Что касается принудительного форсирования, попробуйте добавить два поля в свою пользовательскую таблицу: "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
}

Это заставит вашу систему регистрации распознавать только 3 попытки входа на пользователя каждые 10 минут.

Ответ 2

Не полагайтесь на сеансы или файлы 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 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

Попробуйте проверить, что вы имеете дело с реальным браузером. Возможно, некоторые неприятные скрипты java с именами случайных функций или что-то могут блокировать множество простых скриптов, если они не удаляют управление реальным браузером (что не так уж редко) или правильно оценивают js/css в сценарии скрепера.

Я бы рекомендовал прочитать далее эту тему и протестировать ваше решение против механики python или других известных скребковых инструментов.

Но одно точно, нет реального решения против автоматических атак.