Spring MVC Web 应用程序检测暴力攻击的最佳方法?

Posted

技术标签:

【中文标题】Spring MVC Web 应用程序检测暴力攻击的最佳方法?【英文标题】:Best way for a Spring MVC web app to detect a brute force attack? 【发布时间】:2011-08-06 21:21:56 【问题描述】:

Spring 3.0 MVC 中是否有任何特性可以帮助实现对 Web 应用的身份验证/登录页面的暴力攻击检测?

【问题讨论】:

这取决于您的环境。当您控制服务器环境并记录所有登录尝试时,您可以只使用fail2ban。或者您只是在您的身份验证提供程序或请求过滤器中编写类似 fail2ban 的内容 【参考方案1】:

通过Spring security中的一些配置和编码可以实现。

顺便说一句,我不建议在可疑的无效登录试验前做一些延迟。您可能会延迟响应可疑的登录尝试,但这种延迟会使您在应用程序中暂停线程一段时间。如果您的应用程序同时发生大量无效登录,这可能会对您的系统造成 DoS 或 DDoS 攻击。

更好的方法是对可疑的无效登录做出快速响应,但同时暂停用户尝试登录的用户帐户。这样,暴力攻击避免不会导致提供 Dos 或 DDoS 攻击。

尽管如此,暂停用户帐户也为 DoS 攻击提供了一种途径,因为它可能导致无法向真实用户提供服务。但是,正确的安全方案在这些情况下会有所帮助。 例如,如果检测到暴力攻击,您可以:

显示一些验证码, 暂停帐户,发送电子邮件或短信帐户所有者更改密码 或者,暂停帐户一段时间,同时通知帐户所有者更改密码, ...

所有这些都取决于您的域和服务场景。 例如,您可以实现自己的 UserDetailsS​​ervice 并在此实现中检测暴力攻击。

为了实现 Spring Security 的最后一个场景,下面的代码声明了一个 authentication-manager,它传递了一个自定义的 UserDetailsS​​ervice,这里的类型是 JdbcDaoImpl(注意,包名和查询必须修改为您自己的包和数据模型)。

<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
    <authentication-provider user-service-ref="CustomUserDetailsService" />           
</authentication-manager>

<!--
This bean is to provide jdbc-user-service.
Also, it provides a way to avoid BFD along with AuthenticationFailureListener
-->
<bean id="CustomUserDetailsService" class="com.example.CustomUserDetailsService">
    <property name="dataSource" ref="dataSource" />
    <property name="usersByUsernameQuery" value="SELECT user_client.user_name, user_client.password, user.is_active
                                   FROM user_client INNER JOIN user ON user_client.fk_user = user.ID
                                   WHERE user_client.user_name=? "/>
    <property name="authoritiesByUsernameQuery" value="SELECT user_client.user_name, CONCAT('ROLE_',user_client.client_id)
                                   FROM user_client WHERE user_client.user_name=? "/>
</bean>

CustomUserDetailsS​​ervice 检测是否发生了暴力攻击,以及我将很快讨论的 AuthenticationFailureListener。 FailedLoginCacheManager 是一个 ehcache 包装器,用于维护失败的登录(用户名)及其相对失败的数量。缓存设置了适当的 timeToIdleSeconds 以使帐户暂停。

public class CustomUserDetailsService extends JdbcDaoImpl 

@Autowired
private FailedLoginCacheManager cacheManager;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
    if (cacheManager.isBruteForceAttackLogin(username)) 
     //throw some security exception
     ...
    
    return super.loadUserByUsername(username);

此外,还实现了一个 ApplicationListener 来检测失败的登录尝试并将其保存在 ehcache 中。

@Component public class AuthenticationFailureListener implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> 

@Autowired
private FailedLoginCacheManager cacheManager;

@Override
public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) 
    UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) event.getSource();
    String userName = token.getPrincipal().toString();
    cacheManager.updateLoginFailureStatus(userName);

关于 FailedLoginCacheManager 服务的更多讨论无需赘述,但此处讨论的两个主要方法可以像以下方法一样实现:

public void updateLoginFailureStatus(String userName) 
    Cache cache = manager.getCache(CACHE_NAME);

    Element element = cache.get(userName);
    if (isValid(element)) 
        int failureCount = (Integer)element.getObjectValue();
        cache.remove(userName);
        cache.put(new Element(userName, ++failureCount));
     else 
        cache.put(new Element(userName, 1));
    



public boolean isBruteForceAttackLogin(String username) 
    Cache cache = manager.getCache(CACHE_NAME);
    Element element = cache.get(username);
    if (isValid(element)) 
        int failureCount = (Integer)element.getObjectValue();
        return failureCount >= 3;
     else 
        return false;
    

【讨论】:

【参考方案2】:

简短的回答是否定的,据我所知 Spring 3.0 MVC 没有任何东西可以帮助您检测暴力攻击。我不相信 Spring Security 3.0 在这方面有任何作用。

但是,您应该能够通过扩展一些 UserDetailsS​​ervices 来自己实现一些东西。

有时建议记录所有登录尝试,无论成功与否。如果您正在记录所有故障(例如在数据库中),您应该能够确定是否有人/某物正在尝试对您的站点进行暴力攻击。

您应该考虑像@road to yamburg 所描述的那样限制登录尝试。

【讨论】:

【参考方案3】:

还可以考虑将验证码添加到您的登录页面,来自 Google 的 reCAPTCHA 很容易集成到任何应用程序中。 Here 是用于 Java/JSP 的文档

【讨论】:

【参考方案4】:

久经考验的做法是在身份验证失败时引入随机但相当大的延迟。

这种方式合法用户将立即登录,但攻击者每次尝试将花费 500ms-1 秒,这使得整个暴力破解想法不切实际(将永远存在)。

合法用户偶尔登录失败只会给他们造成轻微的延迟,并且不会被注意到。

如果您需要在重复登录失败时收到通知,您需要实现一个报告,打印每个用户的相应失败登录次数,按该次数 desc 限制 100 排序。

附: Here 是一篇解释如何在登录尝试时获得通知的帖子。我相信,采用同样的方法可能会导致延迟。

【讨论】:

好主意。甚至可以像某些操作系统那样成倍增加延迟时间。【参考方案5】:

令人惊讶的是,我在 Spring MVC 或 Spring Security 的参考文档中找不到任何内容。

不过,我确实找到了 this 3 year old tutorial,它描述了如何使用 Splunk 来完成。

【讨论】:

以上是关于Spring MVC Web 应用程序检测暴力攻击的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

暴力破解与验证码安全

安全测试 web应用安全测试之XXS跨站脚本攻击检测

使用 Spring Security 保护 Web 应用程序免受 CSRF 攻击

Spring MVC通过拦截器处理sql注入跨站XSS攻击风险

C.S.R.F. 的 MVC 4 Web Api 安全性攻击

Spring MVC系列Spring MVC应用及ModelAndView(模型视图)