全站失败登录请求阈值动态公式

问题描述

我正在实施一些安全措施,其中之一是对太多失败请求进行站点范围的限制,以防止分布式暴力攻击。

我遇到的问题是,在多少次失败的登录请求之后,我应该开始节流?
现在一种合理的方法是,正如前面提到的 here “使用您网站的错误登录频率的运行平均值作为上限的基础”。如果该站点平均有 100 次登录失败,则 300(添加了 puffer)可能是一个不错的阈值。

现在我没有运行平均值,我不希望有人随着用户群的增长而主动增加上限。我想要一个根据活跃用户数量计算此限制的动态公式。

困难在于,如果只有少数用户,他们的用户阈值比应该比 10 万用户高得多。这意味着例如对于 50 个用户,限制可以设置为总用户数的 50%,这意味着在给定的时间跨度内允许 25 个站点范围内的失败登录请求。但是对于 10 万用户,这个比率应该会降低,阈值应该更像是 1% 左右。在同一小时内 1000 个失败的登录请求,很多(可能根本不准确,我不是安全专家,数字只是举例说明)。

我想知道,是否有任何数学公式可以以简洁的方式存档?
这是我认为公式应该近似计算的图表:

Graphic of formula

这是我现在所拥有的(我知道这很糟糕,我相信任何建议都会更好):

$threshold = 1;
if ($activeUsers <= 50) {
    // Global limit is the same as the total of each users individual limit
    $threshold *= $activeUsers; // If user limit is 4,global threshold will be 4 * user amount
} elseif ($activeUsers <= 200) {
    // Global requests allows each user to make half of the individual limit simultaneously
    // over the last defined timespan
    $threshold = $threshold * $activeUsers / 2;
} elseif ($activeUsers <= 600) {
    $threshold = $threshold * $activeUsers / 2.5;
} elseif ($activeUsers <= 1000) {
    $threshold = $threshold * $activeUsers / 3.5;
} else { // More than 1000
    $threshold = $threshold * $activeUsers / 5;
}
return $threshold;

解决方法

我最终没有使用一些数学公式,而是使用了不成功与总登录请求的比率。
代码如下所示:

$loginAmountStats = $this->requestTrackRepository->getLoginAmountStats();
// Calc integer amount from given percentage and total login
$allowedFailureAmount = $loginAmountStats['login_total'] / 100 * $this->settings['login_failure_percentage'];
if ($loginAmountStats['login_failures'] > $allowedFailureAmount) {
    // If changed,update SecurityServiceTest distributed brute force test expected error message
    $msg = 'Maximum amount of tolerated requests reached site-wide.';
    throw new SecurityException('captcha',SecurityException::GLOBAL_LOGIN,$msg);
}