mvc mkyong form example java security spring spring-mvc spring-security

java - mkyong - ¿La mejor manera para que una aplicación web de Spring MVC detecte un ataque de fuerza bruta?



spring mvc example (5)

¿Hay alguna característica específica en Spring 3.0 MVC que ayude a implementar la detección de un ataque de fuerza bruta en la página de autenticación / inicio de sesión de una aplicación web?


Es posible mediante algunas configuraciones y codificación en la seguridad Spring.

Por cierto, no sugiero que se produzca un retraso frente a intentos de inicio de sesión no válidos sospechosos. Puede retrasarse un poco para responder a un intento de inicio de sesión sospechoso, pero este retraso le cuesta suspender un hilo por un tiempo en su aplicación. Esto puede proporcionar ataques DoS o DDoS en su sistema si hay una gran cantidad de inicios de sesión no válidos que ocurren simultáneamente en su aplicación.

El mejor enfoque es hacer una respuesta rápida a un inicio de sesión no válido sospechoso, pero al mismo tiempo suspender la cuenta de usuario mediante la cual el usuario está intentando iniciar sesión. De esta manera, la evitación de ataques de fuerza bruta no conduce a la provisión de ataques Dos o DDoS.

Sin embargo, la suspensión de la cuenta de usuario también proporcionaría un camino para el ataque DoS, ya que puede llevar a una falla en la entrega del servicio al usuario real. Pero, los escenarios de seguridad correctos serían útiles en estos casos. Por ejemplo, si se detecta un ataque de fuerza bruta, usted puede:

  • mostrar algo de Captcha,
  • suspender la cuenta, correo electrónico o SMS al propietario de la cuenta para cambiar la contraseña
  • o suspender la cuenta por un período de tiempo al notificar al propietario de la cuenta para que cambie la contraseña,
  • ...

Todo esto depende de su dominio y escenarios de servicio. Como ejemplo, puede implementar su propio UserDetailsService y detectar ataques de fuerza bruta en esta implementación.

Para implementar el último escenario de Spring Security, el siguiente código declara un administrador de autenticación al que se le pasa un UserDetailsService personalizado, cuyo tipo es JdbcDaoImpl aquí (tenga en cuenta que los nombres de paquetes y las consultas deben modificarse a su propio paquete y modelo de datos).

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

El CustomUserDetailsService detecta si hay un ataque de fuerza bruta o no, junto con AuthenticationFailureListener que comento pronto. FailedLoginCacheManager es un contenedor de ehcache que mantiene los inicios de sesión fallidos (nombres de usuario) con sus cantidades relativas fallidas. La memoria caché se configura con un timeToIdleSeconds adecuado para que la suspensión de la cuenta sea temporal.

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

}

Además, se implementa un ApplicationListener para detectar intentos de inicio de sesión fallidos y preservarlos dentro del 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); }}

No es necesario discutir más sobre el servicio FailedLoginCacheManager, pero dos métodos principales que se discuten aquí podrían implementarse como los siguientes métodos:

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


La práctica de larga data es introducir un retraso aleatorio pero considerable si la autenticación ha fallado.

De esta manera, los usuarios legítimos iniciarán sesión de inmediato, pero un atacante gastará 500 ms-1 por intento, lo que hace que la idea de fuerza bruta sea impráctica (se llevará una eternidad).

El inicio de sesión fallido ocasional por usuarios legítimos les causará solo un pequeño retraso y pasará inadvertido.

Si necesita que se le notifique sobre inicios de sesión fallidos repetidos, necesita implementar un número de impresión de informes de inicios de sesión fallidos consecuentes por usuario, ordene por ese número hasta el límite 100.

PS Here hay una publicación que explica cómo recibir una notificación en el intento de inicio de sesión. Siguiendo el mismo enfoque, se puede introducir un retraso, creo.


La respuesta corta es no, que yo sepa, Spring 3.0 MVC no tiene nada que lo ayude a detectar un ataque de fuerza bruta. Tampoco creo que Spring Security 3.0 tenga nada que ver con eso.

Sin embargo, debería poder implementar algo usted mismo extendiendo algunos de los Servicios de Servicios de Usuario.

A veces es recomendable registrar todos los intentos de inicio de sesión, con éxito o no. Si está registrando todos los fallos (como en una base de datos), debería poder determinar si alguien / algo está intentando un ataque de fuerza bruta en su sitio.

Debe considerar los intentos de inicio de sesión limitados, como se describe en @road to yamburg.



También considere agregar captcha a su página de inicio de sesión, reCAPTCHA de Google es muy fácil de integrar en cualquier aplicación. Here está la documentación para usarlo con Java / JSP