防止蛮力攻击的最佳方法是啥?

Posted

技术标签:

【中文标题】防止蛮力攻击的最佳方法是啥?【英文标题】:What is the best method to prevent a brute force attack?防止蛮力攻击的最佳方法是什么? 【发布时间】:2013-03-25 19:14:50 【问题描述】:

我有我的登录页面,当然我想防止暴力攻击并减少用户登录时的延迟。

目前,您输入您的用户名和密码进行登录。

我正在考虑实施reCAPTCHA。但是,这会在 3 次尝试失败后在登录时显示。

我的问题是:

    您尝试的依据是什么。 IP地址?它总是可以隐藏...用户名?如果他们正在尝试一个不存在的用户怎么办?

    计算失败登录尝试的最佳方法是什么?

【问题讨论】:

我会使用会话。 ***.com/questions/9643522/preventing-bruteforce 验证码无效。请参阅这篇文章,了解有关安全性的良好研究。 ***.com/questions/549/… 会话可能会被不接受 cookie 的人“拒绝”。 作为一项更新,根据我的经验,Google 的 ReCAPTCHA3 可以阻止 99% 的机器人,并且非常易于使用。 【参考方案1】:

会话不可靠,因为它们依赖于 cookie,验证码经常被破坏 [包括 ReCAPTCHA]。唯一可靠的方法看似简单:问一个问题。不要使用数学问题,因为计算机出于某种原因令人惊讶地擅长解决这些问题。伟大的旧备用是这样的:

this page 第六段第四个字是什么? 这个网站的作者叫什么名字? [hint]

这是愚蠢的——容易实现,机器很难解决。

至于强制强制,请尝试在您的用户表中添加两个字段,“first_failed_login”[INTEGER unix 时间戳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 次登录尝试。

【讨论】:

很好的答案,但这仅在黑客试图攻击已经存在的用户时才有意义,并且当黑客试图暴力破解真实用户时,它也会锁定真实用户。 @user2721465 1. 你究竟如何暴力破解一个不存在的用户? 2. 如果没有密码,你如何区分真实用户和冒名顶替者?可以允许真正的用户通过电子邮件或其他方式在带外解锁他们的帐户,但这超出了问题的范围。 @Sammitch 这种机制将允许攻击者在尝试查找真实用户帐户时重复登录,并且他会知道何时找到,因为暴力措施仅在尝试登录时发生作为真正的用户。 @dlofrodloh 和改革是正确的。攻击者可以注意到真正的用户。然而,这仍然是一个很好的答案,“如果”你结合了这种使用缓存的保护方法。 (coderwall.com/p/sauviq/brute-force-protection-in-php) @Accountantم 因为那样你需要做的就是使用多个 IP 地址,保护毫无意义。【参考方案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'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】:

尝试检查您使用的是真实浏览器。 也许一些带有随机函数名或其他东西的讨厌的 java 脚本挑战可能会阻止很多简单的脚本,除非它们远程控制真正的浏览器(这并不罕见),或者在爬虫脚本中正确评估 js/css。

我建议您进一步阅读该主题,并针对 python mechanize 或其他一些知名的爬虫工具测试您的解决方案。

但可以肯定的是,没有针对自动攻击的真正解决方案。

【讨论】:

以上是关于防止蛮力攻击的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

防止令牌共享的最佳方法是啥?

在 CodeIgniter 中防止 SQL 注入的最佳方法是啥 [重复]

在 Linux 上防止内存不足 (OOM) 冻结的最佳方法是啥?

锁定文件以防止多个用户访问它的最佳方法是啥

防止用户在后台处理时单击表单上的任何内容的最佳方法是啥? [关闭]

防止机器人向您的博客发送垃圾邮件的最佳方法是啥?