views:

410

answers:

2

My web applications security is handled by Spring Security 3.02 but I can't find any out of the box support for Brute Force Detection.

I would like to implement some application level BFD protection. For example by storing failed login attempt per user in the database (JPA). The attacked user accounts could then get a lockout period or a forced account re-activation by e-mail.

What's the best way to implement this with Spring Security? Does any body have example code or best practices on this?

+1  A: 

The normal way to do detect brute force attacks (password guessing) is to have the authentication scheme log failed login attempts, and have a separate application attempt to detect suspicious patterns in the log file. I guess it would be possible to close the loop and have the detector take action to lock accounts under attack, etc.

There is an example on this page.

Stephen C
Thanks! You're link pointed me in the right direction.
Kdeveloper
+1  A: 

It's not that hard to role you're own BFD. As in Spring Security 3.0 you can simply add Application listeners (thanks Stephen C for pointing me in the correct direction).

This listener will be called when authentication failures appear:

@Component
public class AuthenticationFailureListener
  implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {

  @Autowired
  private UserDao userDao;

  public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent ev) {

    String username = ev.getAuthentication().getName();

    User user = userDao.find("name", username);
    if (user != null) { // only for existing users
            user.reportLoginFailure();
            userDao.commit();
    }
}

}

Each authentication failure will now inform the user. The user for example increments an authentication failure counter and deactivates it self when a certain threshold is reached.

When a user is correctly authenticated the below listener will inform the user (who for example can reset it’s authentication failure counters):

@Component
public class AuthenticationSuccessEventListener
  implements ApplicationListener<AuthenticationSuccessEvent>{

  @Autowired
  private UserDao userDao;

  public void onApplicationEvent(AuthenticationSuccessEvent event) {

    String username = event.getAuthentication().getName();

    User user = userDao.find("name", username);
    user.reportLoginOK();
    userDao.commit();
}

}

The above listeners will not need additional XML configuration and are picked up automatically by Spring (if they are in Spring component-scan package).

Depending on you transaction configuration this solution could miss some failed login counts if they happen near simultaneously. This can be prevented if you update the counter with a single UPDATE query instead of loading the user and then save the changes.

Above listeners can also be extended to detect other BDF patterns, for example a single IP that is doing a scan on lot’s of (random) user names.

Kdeveloper