如何在多次尝试后延迟登录尝试 (PHP)
我正在开发一个用 PHP 构建的相当大的网站,该网站可能会有很多用户。 我正在寻找一种方法来保护登录屏幕免受自动尝试的影响。 我已经在注册表中添加了验证码检查,但还想进一步强化网站。
据我所知,StackOverflow 上也有类似的问题,而且我知道我有能力自己从头开始实现这一点(将登录尝试及其时间存储在数据库中),但我不喜欢这条路径:
- 从概念上讲,我认为这种逻辑属于 Web 服务器/基础设施级别,而不是应用程序级别。 我不喜欢在我的应用程序中使用这种逻辑和复杂性,
- 我担心性能,特别是在数据库级别。
- 我很懒,以一种好的方式,不想从头开始构建这样的通用实用程序
任何建议都表示赞赏,我认为我特别在寻找某种可以做到这一点的 Apache 模块。 我的平台是PHP5(使用CodeIgniter)、Apache2、MySQL 5。
I'm working on a fairly large web site built in PHP that will potentially have a lot of users. I'm looking into a way to protect the login screen from automated attempts. I have already included a CAPTCHA check on the registration form, yet want to harden the site more.
There have been similar questions on StackOverflow that I know of, and I know I'm capable of implementing this myself from scratch (storing login attempts and their time in the db), yet I dislike that path:
- Conceptually, I think this kind of logic belongs at the web server/infrastructure level, not the application level. I dislike having this logic and complexity in my application
- I worry about performance, particularly at the database level.
- I'm lazy, in a good way, by not wanting to build a common utility like this from scratch
Any advise is appreciated, I think that I'm particularly looking for some kind of Apache module that can do this. My platform is PHP5 (using CodeIgniter), Apache2, MySQL 5.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
更新:不要使用 sleep() 进行速率限制!这根本没有意义。 我手头没有更好的解决方案。
一个好的开始是在登录尝试失败后
sleep(1);
- 易于实现,几乎没有错误。1 秒对于人类来说并不算多(特别是因为人类的登录尝试不会经常失败),但是 1 秒/尝试暴力......慢! 字典攻击可能是另一个问题,但它属于同一域。
如果攻击者启动过多的连接来规避此问题,您将面临一种 DOS 攻击。 问题解决了(但现在你又遇到了另一个问题)。
您应该考虑一些事情:
我的建议:
完全锁定是不可取的(DOS),因此更好的选择是:计算来自唯一 IP 的特定用户名的登录尝试。 您可以使用简单的表
failed_logins: IP/username/failed_attempts
来完成此操作,如果登录失败,则等待 (failed_attempts); 秒。 每 xx 分钟运行一个 cron 脚本,将
failed_logins:failed_attempts
减一。抱歉,我无法提供预制解决方案,但这应该很容易实现。
好吧好吧。 这是伪代码:
免责声明:这可能在某些地区不起作用。 我听到的最后一件事是,在亚洲有一个完整的国家 NATed(而且,他们都懂功夫)。
update: do not use sleep() for rate limiting! this doesn't make sense at all. i don't have a better solution on hand.
a good start would be to just
sleep(1);
after a failed login attempt - easy to implement, almost bug-free.1 second isn't much for a human (especially because login attempts by humans don't fail to often), but 1sec/try brute-force ... sloooow! dictionary attacks may be another problem, but it's in the same domain.
if the attacker starts too may connections to circumvent this, you deal with a kind of DOS-attack. problem solved (but now you've got another problem).
some stuff you should consider:
my suggestion:
complete locking is not desireable (DOS), so a better alternative would be: count the login attempts for a certain username from a unique IP. you could do this with a simple table
failed_logins: IP/username/failed_attempts
if the login fails,
wait(failed_attempts);
seconds. every xx minutes, run a cron script that decreasesfailed_logins:failed_attempts
by one.sorry, i can't provide a premade solution, but this should be trivial to implement.
okay, okay. here's the pseudocode:
disclaimer: this may not work in certain regions. last thing i heard was that in asia there's a whole country NATed (also, they all know kung-fu).
一个非常虚拟的未经测试的示例,但我认为,您会在这里找到主要思想)。
抱歉,我犯了错误 - 我在几秒钟内写了它,广告没有测试......
您可以通过 IP、昵称、session_id 等进行同样的操作...
A very dummy untested example, but I think, you will find here the main idea ).
Sorry for the mistakes - I wrote it in some seconds ad didn't test...
The same you can do by IP, by nickname, by session_id etc...
为什么不等待“强化”和“扩展”你的应用程序,直到你真正遇到这个问题呢? 最有可能的情况是该应用程序永远不会拥有“大量用户”。 对我来说,这听起来像是过早的优化,需要避免。
Why don't you wait with "hardening" and "scaling" your app until you actually have that problem? Most likely scenario is that the app will never have "a lot of users". This sounds like premature optimization to me, something to avoid.