Solicitud de bloque para múltiples inicios de sesión fallidos por un período de tiempo

Tengo un sitio web y quiero bloquear la solicitud de los BOTs e bash de iniciar sesión con fuerza bruta en mi sitio web.

Ahora estoy usando la Session para almacenar el bash de inicio de sesión y mostrar el captcha después de 3 inicios de sesión fallidos, pero hay un problema. La sesión se eliminará, si el usuario cierra el navegador.

¿Qué tipo de solución debería considerar para evitar los BOTs y el inicio de sesión de fuerza bruta? ¿Qué propiedad del sistema de usuario o del navegador debo almacenar para administrar su siguiente inicio de sesión?

Editar 1)

No uso el proveedor de membresía ASP.NET. Estoy usando mis propias clases de autenticación y autorización

No puede usar la sesión, ya que requiere que el cliente almacene una cookie para usted, y un atacante no lo ayudará. Necesitarás un estado global.

No necesita molestarse en rastrear las direcciones IP, ya que un tipo malo simplemente usará un Proxy Anonymyzing.

No use el locking de la cuenta a menos que tenga que hacerlo (requisito de PCI), ya que esto solo permite que el atacante haga lo correcto con sus usuarios.

También querrá evitar hacer sus deberes haciendo que su servidor trabaje demasiado.

Esto funciona:

Tras la autenticación incorrecta, almacene el nombre de usuario en estado global, junto con el recuento. count++ sincronizado count++ si hay más autenticaciones fallidas con ese nombre de usuario. Yo uso redis para esto.

Si count >= threshold , entonces la demanda resolvió el valor de CAPTCHA antes de continuar. Mostrar CAPTCHA en la pantalla de inicio de sesión.

Tras la autenticación exitosa , borre el nombre de usuario almacenado en estado global. Dele al usuario “agente de usuario de confianza” la cookie HMAC, para que no tenga que CAPTCHA en el futuro para ese nombre de usuario en ese UA.

Puede hacer lo mismo para las contraseñas , pero probablemente con un umbral más alto.

Si no le gusta CAPTCHA , solicite una Prueba de trabajo, por ejemplo, haciendo que el cliente calcule y presente los factores primos de un número muy grande.

Mientras estás en ello, asegúrate de estar usando bcrypt para hash tus contraseñas, y de que el factor de costo es lo suficientemente alto como para llevar hash una contraseña a> = 250 ms. Esto ralentiza su servidor pero también ralentiza a un atacante. Evite el hashing a menos que pasen el CAPTCHA (si es necesario).

¿Alienta a los usuarios a usar contenido largo, complicado y memorable? contraseñas, para que sean más difíciles de usar con fuerza bruta.

Lo más fácil sería hacer frente a su solución con un proveedor de CDN como cloudflare ( https://www.cloudflare.com/features-security ) que detectará los bots por usted. Muchos de los CDN ofrecen esto, y cloudflare tiene una tarifa gratis.

Alternativamente, si está intentando hacer esto usted mismo, puede contar la cantidad de bashs por nombre de usuario en su base de datos y presentar un captcha basado en este conteo.

Identifique el inicio de sesión no válido según IpAddress (proxy anónimo). Que cada sesión inválida de inicio de sesión y sesión y tiempo de IP se almacenarán en el estado de la aplicación.

Crear clase InvalidLogin

 public class InvalidLogin { public string IP { get; set; } public DateTime Attempttime { get; set; } public int AttemptCount { get; set; } } 

Evento de ingreso

 protected void Login_Click(object sender, EventArgs e) { bool Testsuccessfullogin = false; if (Testsuccessfullogin) { //Your code after successfull login } else { //Invalid Login --- Capture Each login event based on IP string strIp; strIp = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; //when user is behind proxy server if (strIp == null) { strIp = Request.ServerVariables["REMOTE_ADDR"];//Without proxy } List user = null; if (HttpContext.Current.Application["Users"] == null) //Adding List to Application State { user = new List(); } else { user = (List)HttpContext.Current.Application["Users"]; } var remove = user.RemoveAll(x => x.Attempttime < DateTime.Now.AddMinutes(-15));//Remove IP Before 15 minutes(Give 15 Min Time Next Login) var checkLogged = user.Find(x => x.IP == strIp); if (checkLogged == null) { user.Add(new InvalidLogin { IP = strIp, Attempttime = DateTime.Now, AttemptCount = 1 }); Application.Lock(); HttpContext.Current.Application["Users"] = user; Application.UnLock(); } else { if (checkLogged.AttemptCount < 4) { checkLogged.Attempttime = DateTime.Now; checkLogged.AttemptCount++; Application.Lock(); HttpContext.Current.Application["Users"] = user; Application.UnLock(); } } if (checkLogged != null) { if (checkLogged.AttemptCount > 3) { captcha.Visible = true; //Showing captcha } } } } 

Si está utilizando sus propias clases de autenticación y autorización, debe contar la cantidad de bashs fallidos para iniciar sesión para cada usuario y su fecha y hora.

Si se alcanza el número de bashs, se limita el siguiente proceso de inicio de sesión con un mensaje de error como “Su cuenta estuvo bloqueada durante 15 minutos, intente de nuevo más tarde”.

Por ejemplo. La tabla de inicios de sesión se denomina [Inicios de sesión].

 You need to add new colums: 1. [LastLoginAttemptAt] DATETIME NULL 2. [LoginFailedAttemptsCount] INT NOT NULL DEFAULT 0 

Por lo tanto, su clase de inicio de sesión tendrá estos nuevos campos:

 public class Login { public DateTime? LastLoginAttemptAt {get;set;} public int LoginFailedAttemptsCount {get;set;} } 

También necesita almacenar alguna variable de configuración: el valor de la cantidad máxima de bashs fallidos para iniciar sesión y bloquear el período.

 const int MaxNumberOfFailedAttemptsToLogin = 10; const int BlockMinutesAfterLimitFailedAttemptsToLogin = 15; // 15 min 

En un método de inicio de sesión, usted hará lo siguiente (ejemplo primitivo de código, no una versión prod):

 public void SignIn(string username, string password) { var login = _userService.TryGetLogin(username); if (login == null){ // Login by username not found. // Return error message "Invalid username or password" return; } if (login.LoginFailedAttemptsCount > MaxNumberOfFailedAttemptsToLogin && login.LastLoginAttemptAt.HasValue && DateTime.Now < login.LastLoginAttemptAt.Value.AddMinutes(BlockMinutesAfterLimitFailedAttemptsToLogin)) { // Login is blocked, need to break the process. // Return error message "Your account was blocked // for a 15 minutes, please try again later." return; } else { login.LoginFailedAttemptsCount = 0; login.LastLoginAttemptAt = DateTime.Now; } var success = login.ValidatePassword(password); if (!success) { // Invalid password, need to update the number of attempts. login.LastLoginAttemptAt = DateTime.Now; //or UTC login.LoginFailedAttemptsCount++; // Update(login); // Return error message "Invalid username or password" return; } else { login.LoginFailedAttemptsCount = 0; login.LastLoginAttemptAt = DateTime.Now; // Update(login); // Success! } } 

Puede suspender la cuenta después de algunos bashs fallidos y tener preguntas de seguridad de respuesta del usuario para volver a habilitarla. Tampoco permita la reutilización de las últimas contraseñas y debe estar seguro.

Ahora dicho esto, si desea hacerlo a través de la encoding, guarde el tercer tiempo de bash de inicio de sesión [MaxAttemptTime] ( DateTime.Now ) y la hora de liberar la cuenta [ReleaseTime] (digamos después de 20 minutos DateTime.Now.AddMinutes(20) ) .

Ahora, cada vez que hay un bash del mismo usuario para iniciar sesión, se debe rechazar en función de [ReleaseTime] . Restablezca estos contadores en el inicio de sesión exitoso para un usuario genuino.

Lo único que me gustaría añadir que otros no tienen es que, donde sea posible, no querrás alertar a los robots sobre el hecho de que han sido detectados. si los bloquea con algún mensaje, entonces solo tomarán nota de lo que hicieron para detectar y ajustar. Si los está “notando” por vía ip, por ejemplo, simplemente no permita que la contraseña que están ingresando tenga éxito. se los engañará para que piensen que tienen contraseñas complicadas, etc., y se irán a otro lado, sin siquiera saber con certeza si los han notado.

También sugiero almacenar los “bashs” en una base de datos con ip. A continuación, puede volver fácilmente y revisar los bashs que se han realizado contra su sitio. puedes consultar los registros web, pero eso es más doloroso. También registro inicios de sesión exitosos para poder notar cuándo entran los bots para volver atrás y aplicar más investigaciones.

Si estuviera haciendo esto, usaría una columna en una base de datos para almacenar el número de bashs de inicio de sesión y una marca de fecha y hora para el primer bash. Entonces tenga algo de lógica sobre el inicio de sesión

  if(loginAttempt>5 && DateTime.Now