我正在尝试使用 session 来存储登录尝试次数。当达到最大登录尝试次数时,我会将客户端的 IP 地址存储在黑名单表中。
我已经考虑到的一些事情,您可能需要了解:
- 我在设置 session 值后使用
session_regenerate_id();
。 - 除了 session 之外,我没有使用任何 cookie,因为这不是必需的,也不是 2012 :p
- 用户 ip 被列入黑名单,直到我手动从黑名单表中删除他的行。
SESSION_MAX_ATTEMPTS
是定义的常量并设置为 5。index.php?module=login&task=blacklist
页面只是向用户显示它已被列入黑名单的消息。该页面没有任何功能。- 我正在使用自定义构建的 php 框架,所以我必须将一些称为方法的 OOP 转换为简化的 php 代码。
在执行登录查询之前调用以下函数:
private function preventAttack()
{
$blocked = getData("SELECT count(*) as blocked FROM blacklist WHERE ip = @Value0;", Array( $_SERVER['REMOTE_ADDR'] ));
if($blocked[0]["blocked"] == "1")
{
redirect("index.php?module=login&task=blacklist");
}
$old = (int)$this->session->get("login_attempts");
if(!empty($old))
{
if($old > SESSION_MAX_ATTEMPTS)
{
setData("INSERT INTO blacklist SET ip = @Value0;", Array( $_SERVER['REMOTE_ADDR'] ));
redirect("index.php?module=login&task=blacklist");
}
else
{
$old++;
$this->session->set("login_attempts",$old);
}
}
else
{
$this->session->set("login_attempts", 0);
}
}
第一个 if 语句适用于两个查询,但我一直停留在什么是存储尝试次数的最佳方式以及什么是++ 的最佳方式?也许你们可以让我朝着正确的方向前进。
如果您对我的代码有任何疑问,请添加评论。我知道它有点不可读,因为它来 self 的框架,在发布之前我已经翻译了一下。
最佳答案
将失败尝试次数存储在数据库中,而不是 session 中。 N.B.:您可能需要在其自己的记录中保留每个失败及其时间戳(并忽略/删除任何早于阈值的内容)。
顺便回应一下deceze的评论:
Ginormous flaw in this approach: sessions depends on the client sending a cookie. Real attackers will simply not send the cookie back. ziiiing You'll have to go by IP for everything.
对此的解决方案是,您不接受没有在其他地方设置的有效 session cookie 的登录尝试。
关于php - 使用 php 中的 session 防止对登录的攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11503261/