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

发布于 2024-11-01 22:15:16 字数 66 浏览 2 评论 0原文

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

Are there any features specifically in Spring 3.0 MVC that would help implementing detection of a brute force attack on the authentication/login page of a web app?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一指流沙 2024-11-08 22:15:16

长期证明的做法是,如果身份验证失败,则引入随机但相当大的延迟。

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

合法用户偶尔登录失败只会导致轻微的延迟,并且不会被注意到。

如果您需要收到有关重复登录失败的通知,则需要实现一个报告,打印每个用户的后续登录失败次数,按该数字 desc limit 100 排序。

PS 这里是一篇解释如何在登录尝试时收到通知的帖子。我相信,采用相同的方法可能会导致延迟。

Long-proven practice is to introduce a random but sizable delay if authentication has failed.

This way legitimate users will log on right away, but an attacker will spend 500ms-1s per try, which makes the whole brute-force idea impractical (will take forever).

Occasional failed login by legitimate users will cause them only a minor delay and will go unnoticed.

If you need to be notified on repeated failed logins, you need to implement a report printing number of consequential failed logins per user, order by that number desc limit 100.

P.S. Here is a post explaining how to get notified on login attempt. Following the same approach one can introduce a delay, I believe.

初与友歌 2024-11-08 22:15:16

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

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

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

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

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

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

为了通过 Spring Security 实现最后一个场景,以下代码声明了一个身份验证管理器,该管理器传递一个自定义的 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;
    }
}

It is possible by some configurations and coding in Spring security.

By the way, I do not suggest to make some delay in front of suspicious invalid login trials. You may make some delay to respond to a suspicious login attempt but this delay costs you to suspend a thread for a while in your application. This may provide DoS or DDoS attack on your system if there are high amount of invalid logins happen simultaneously to your application.

The better approach is to make a fast response to a suspicious invalid login but at the same time to suspend the user account by which the user is trying to login. In this way, brute force attack avoidance does not lead to provision of Dos or DDoS attack.

Nevertheless, suspension of user account would also provide a way for DoS attack, for it may lead to failure in delivery of service to real user. But, correct security scenarios would be helpful in these cases.
For example, if a brute force attack is detected, you may:

  • show some Captcha,
  • suspend the account, email or SMS the account owner for password change
  • or, suspend the account for a period of time while notifying the account owner for password change,
  • ...

All of this depends to your domain and service scenarios.
As an example, you may implement your own UserDetailsService and detect brute force attack in this implementation.

To implement the last scenario by Spring Security, the following code declares an authentication-manager which is passed a custom UserDetailsService which type is JdbcDaoImpl here (Note that package names and queries must be modified to your own package and data model).

<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>

The CustomUserDetailsService detects if there is a brute force attack happening or not, along with AuthenticationFailureListener that I discuss soon. FailedLoginCacheManager is a ehcache wrapper that maintains the failed logins (usernames) with their relative failed amounts. The cache is set with a proper timeToIdleSeconds to make the account suspension temporary.

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);
}

}

Also, a ApplicationListener is implemented to detect failed login attempts and preserve them inside the 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);
}}

There is no need to discuss more about FailedLoginCacheManager service but two main methods that are discussed here could be implemented like the following methods:

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;
    }
}
生生不灭 2024-11-08 22:15:16

令人惊讶的是,我在参考文档中找不到 Spring MVC春天安全

然而,我确实找到了 这个已有 3 年历史的教程介绍了如何使用 Splunk 来完成此操作。

Surprisingly, I couldn't find anything in the reference docs for either Spring MVC or Spring Security.

I did, however, find this 3 year old tutorial that describes how it can be done using Splunk.

别想她 2024-11-08 22:15:16

还可以考虑将验证码添加到您的登录页面,Google 的 reCAPTCHA 非常容易集成到任何应用程序中。 这里是有关将其与 Java/JSP 一起使用的文档

Also consider adding captcha to your login page, reCAPTCHA from Google is very easy to integrate to any application. Here is documentation for using it with Java/JSP

冷弦 2024-11-08 22:15:16

简而言之,答案是否定的,据我所知 Spring 3.0 MVC 没有任何东西可以帮助您检测暴力攻击。我不相信 Spring Security 3.0 有任何与此相关的东西。

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

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

您应该考虑限制登录尝试,例如@road to yamburg 所描述的。

The short answer is no, as far as I know Spring 3.0 MVC does not have anything to help you detect a brute force attack. I don't believe spring security 3.0 has anything either for that matter.

However, you should be able to implement something yourself by extending some of the UserDetailsServices.

It is sometimes advisable to record all login attempts, successful or not. If you're recording all failures (like in a database) you should be able to determine if someone/something is attempting a brute force attack on your site.

You should consider throttling login attempts like @road to yamburg described.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文