Muy bien, suficiente retraso; esto es lo que se me ocurrió hasta ahora
(perdón, larga publicación por delante. Sé valiente, amigo, el viaje valdrá la pena)
Combinando los métodos 3 y 4 de la publicación original en una especie de lista blanca 'difusa' o dinámica, y luego, y aquí está el truco, no bloquear las IP no incluidas en la lista blanca, simplemente estrangularlas al infierno y viceversa .
Tenga en cuenta que esta medida solo pretende frustrar este tipo de ataque muy específico. En la práctica, por supuesto, funcionaría en combinación con otros enfoques de mejores prácticas para la autenticación: limitación de nombre de usuario fijo, limitación por IP, política de contraseña segura con código, inicio de sesión de cookie sin estrangulamiento, hash todos los equivalentes de contraseña antes de guardarlos, nunca utilizando preguntas de seguridad, etc.
Suposiciones sobre el escenario de ataque
Si un atacante apunta a nombres de usuario variables, nuestra limitación de nombre de usuario no se activa. Si el atacante está usando una botnet o tiene acceso a un amplio rango de IP, nuestra limitación de IP es impotente. Si el atacante ha eliminado previamente nuestra lista de usuarios (generalmente posible en servicios web de registro abierto), no podemos detectar un ataque continuo en función de la cantidad de errores de "usuario no encontrado". Y si aplicamos una restricción restrictiva en todo el sistema (todos los nombres de usuario, todas las IP), cualquier ataque de este tipo afectará a todo nuestro sitio durante la duración del ataque más el período de limitación.
Entonces necesitamos hacer algo más.
La primera parte de la contramedida: lista blanca
De lo que podemos estar bastante seguros es que el atacante no puede detectar y falsificar dinámicamente las direcciones IP de varios miles de nuestros usuarios (+). Lo que hace factible la lista blanca . En otras palabras: para cada usuario, almacenamos una lista de las IP (hash) desde donde el usuario ha iniciado sesión (recientemente) previamente.
Por lo tanto, nuestro esquema de listas blancas funcionará como una 'puerta principal' bloqueada, donde un usuario debe estar conectado desde una de sus IP 'buenas' reconocidas para poder iniciar sesión. Un ataque de fuerza bruta en esta 'puerta principal' sería prácticamente imposible (+).
(+) a menos que el atacante 'posea' el servidor, todos los cuadros de nuestros usuarios o la conexión en sí misma, y en esos casos, ya no tenemos un problema de 'autenticación', tenemos un verdadero pull-the de tamaño de franquicia -enchufe la situación FUBAR
La segunda parte de la contramedida: aceleración de IP no reconocidas en todo el sistema
Para que una lista blanca funcione para un servicio web de registro abierto, donde los usuarios cambian de computadora con frecuencia y / o se conectan desde direcciones IP dinámicas, necesitamos mantener abierta una 'puerta de acceso' para los usuarios que se conectan desde IP no reconocidas. El truco es diseñar esa puerta para que las botnets se atasquen y los usuarios legítimos se molesten lo menos posible .
En mi esquema, esto se logra al establecer un número máximo muy restrictivo de intentos fallidos de inicio de sesión por IP no aprobadas durante, por ejemplo, un período de 3 horas (puede ser más prudente usar un período más corto o más largo según el tipo de servicio), y haciendo que esa restricción sea global , es decir. para todas las cuentas de usuario.
Incluso una fuerza bruta lenta (1-2 minutos entre intentos) se detectaría y frustraría de manera rápida y efectiva utilizando este método. Por supuesto, una fuerza bruta realmente lenta aún podría pasar desapercibida, pero velocidades demasiado lentas derrotan el propósito mismo del ataque de fuerza bruta.
Lo que espero lograr con este mecanismo de estrangulamiento es que si se alcanza el límite máximo, nuestra 'puerta de gato' se cierra por un tiempo, pero nuestra puerta principal permanece abierta para usuarios legítimos que se conectan por los medios habituales:
- Ya sea conectándose desde una de sus IP reconocidas
- O mediante el uso de una cookie de inicio de sesión persistente (desde cualquier lugar)
Los únicos usuarios legítimos que se verían afectados durante un ataque, es decir. mientras se activaba la limitación, serían los usuarios sin cookies de inicio de sesión persistentes que iniciaran sesión desde una ubicación desconocida o con una IP dinámica. Esos usuarios no podrán iniciar sesión hasta que la aceleración desaparezca (lo que podría llevar un tiempo si el atacante mantiene su botnet funcionando a pesar de la aceleración).
Para permitir que este pequeño subconjunto de usuarios se filtre a través de la puerta para gatos sellada de otro modo, incluso cuando los bots todavía la estaban golpeando, emplearía un formulario de inicio de sesión de 'respaldo' con un CAPTCHA. De modo que, cuando muestre el mensaje "Lo siento, pero no puede iniciar sesión desde esta dirección IP en este momento", incluya un enlace que diga " inicio de sesión seguro de respaldo - SOLO HUMANOS ( bots: no mentir ) ". Broma a un lado, cuando hacen clic en ese enlace, les dan un formulario de inicio de sesión autenticado reCAPTCHA que evita la limitación en todo el sitio. De esa manera, SI son humanos Y conocen el inicio de sesión + contraseña correctos (y son capaces de leer CAPTCHA), nunca se les negará el servicio, incluso si se conectan desde un host desconocido y no usan la cookie de inicio de sesión automático.
Ah, y solo para aclarar: dado que considero que los CAPTCHA son generalmente malos, la opción de inicio de sesión de 'copia de seguridad' solo aparecerá mientras la aceleración esté activa .
No se puede negar que un ataque sostenido como ese todavía constituiría una forma de ataque DoS, pero con el sistema descrito en su lugar, solo afectaría lo que sospecho que es un pequeño subconjunto de usuarios, es decir, personas que no usan el la cookie "recordarme" Y está iniciando sesión mientras ocurre un ataque Y no está iniciando sesión desde ninguna de sus IP habituales Y que no pueden leer CAPTCHA. Solo aquellos que pueden decir NO a TODOS esos criterios, específicamente los bots y las personas discapacitadas realmente desafortunadas , serán rechazados durante un ataque de bot.
EDITAR: En realidad, pensé en una forma de permitir que incluso los usuarios con problemas de CAPTCHA pasen durante un 'bloqueo': en lugar de, o como complemento del inicio de sesión de CAPTCHA de respaldo, proporcionar al usuario la opción de tener un solo uso , código de bloqueo específico del usuario enviado a su correo electrónico, que luego puede usar para evitar la limitación. Esto definitivamente cruza mi umbral de 'molestia', pero dado que solo se usa como último recurso para un pequeño subconjunto de usuarios, y dado que aún supera el bloqueo de su cuenta, sería aceptable.
(Además, tenga en cuenta que nada de esto sucede si el ataque es menos sofisticado que la desagradable versión distribuida que describí aquí. Si el ataque proviene de unas pocas IP o solo golpea algunos nombres de usuario, se frustrará mucho antes) y sin consecuencias para todo el sitio)
Entonces, esa es la contramedida que implementaré en mi biblioteca de autenticación, una vez que esté convencido de que es sólido y de que no hay una solución mucho más simple que me haya perdido. El hecho es que hay muchas maneras sutiles de hacer las cosas mal en seguridad, y no estoy por encima de hacer suposiciones falsas o lógicas irremediablemente defectuosas. Así que por favor, todos y cada uno de los comentarios, críticas y mejoras, sutilezas, etc. son muy apreciados.