2009-01-19 65 views
11

我想实现一个有效的机制来限制我的Java Web应用程序中的登录尝试,以防止对用户帐户进行暴力攻击。如何在Java webapp中限制登录尝试?

Jeff explained the why, but not the how.

西蒙·威利森呈implementation in Python for Django: 这并不真正帮助我一起,因为我不能使用memcached的也不Django的。

移植从头开始他的想法似乎并不像一个伟大要么 - 我不想推倒重来。

我发现一个Java implementation,但它似乎相当naiive:取而代之的是LRU缓存,它只是清除15分钟后所有条目。

的EHCache可能是memcached的替代方案,但我没有任何与它的经验,真的不希望,如果有这个任务更好的替代品,以intoduce另一种技术。

所以,什么在Java中实现登录节流的好办法?

回答

1

我刚刚完成了由方面安全性运行的网络安全课程,其中的一个建议是仅包含任何登录尝试的自然延迟 - 理论上说1或2秒延迟对于真实用户来说没有任何意义,但会严重阻碍暴力攻击。

+0

虽然任何登录可能会导致用户体验不佳。 – Loki 2009-01-19 14:03:27

+0

任何失败的登录在unix世界中都是标准的,但是web应用程序部分意味着攻击者可以在多个线程中执行此操作,所以简单的超时将不会执行,您必须将登录尝试存储在某个地方并创建一些代码来访问并验证它。 – Loki 2009-01-19 14:11:08

+0

只是延迟所有尝试并不能阻止某人平行运行50个请求。这就是为什么Simon Willison将IP地址和时间戳一起存储在缓存中。 – 2009-01-19 14:48:05

7

我认为即使EHCache正在用凝固汽油弹炸死一只苍蝇。问题很简单,实施也是如此。

我建议使用一个servlet过滤器顶部水平,使尽可能少的处理尽可能完成。

创建类来存储以下内容:

  • 尝试的数目(计数)
  • 的时间

现在,该代码是在一个sunchronized块简单:

if userid not in attemptMap: 
    attemptMap.add (userid, new attemptItem (userid, 1, now)) 
else 
    tmp = attemptMap.get (userid) 
    if (acquire lock for tmp) : 
     if tmp.time + 30 > now : 
      tmp.count = 0 
      tmp.time = now 
     tmp.count++ 
     if tmp.count > 3 : 
      error=true 
     release lock for tmp 
    else : error=true 

这就是它的人(只要代码是同步的)。

0

我已经在用户详细信息中使用了Login Attempt计数字段。当它达到50时,正确的密码将被拒绝,用户必须执行密码重置。

0

登录尝试之间的时间指数增长情况如何?尚未提及

1

一个是让他们回答忘记密码问题(S)这么多的错误尝试+输入自己的密码后,

0

的EHCache是​​相当不错的,而且更重要的是不写的你,所以你不要不必重新实现功能,可能会让他们错误。

我的解决方案将涉及任何的EHCache还是最简单的登录代码(如果它是一个小的应用程序,我并没有真正关心的并发性能)。

根据IP,您将存储失败计数和时间戳。

  • 每次您进行登录尝试,锻炼是否允许他们使用失败计数和时间戳。
  • 每次您进行允许的登录尝试并失败时,将失败的计数增加1并记录失败时间。
  • 每次您进行允许的登录尝试并成功清除该IP的信息时。
0

保持错误的登录尝试次数,如果它将达到N,则阻止用户并要求验证码或密码重置以继续。