Подтвердить что ты не робот

Запросить блокировку нескольких неудачных логинов в течение определенного периода времени

У меня есть веб-сайт, и я хочу заблокировать запрос от BOTs и попытаться войти в систему на моем веб-сайте.

Теперь я использую Session для сохранения попытки входа в систему и отображения кода после 3 неудачных логинов, но есть проблема. Сессия будет удалена, если пользователь закроет браузер.

Какое решение я должен учитывать для предотвращения входа BOTs и переборщика? Какое свойство пользовательской системы или браузера я должен хранить, чтобы управлять его/ей следующим входом?

Изменить 1)

Я не использую поставщика членства ASP.NET. Я использую свои собственные классы проверки подлинности и авторизации

4b9b3361

Ответ 1

Вы не можете использовать сеанс, так как он требует, чтобы клиент хранили файл cookie для вас, и злоумышленник не поможет вам. Вам понадобится какое-то глобальное состояние.

Вам не нужно беспокоиться о отслеживании IP-адресов, так как плохой парень просто будет использовать прокси-сервер Anonymyzing.

Не использовать блокировку учетной записи, если только вам не требуется (требование PCI), так как это позволяет злоумышленнику делать ваши пользователи.

Вы также хотите избежать DoS-ов себя, сделав ваш сервер слишком много работы.

Это работает:

После неудачной аутентификации сохраните имя пользователя в глобальном состоянии вместе с count. Синхронизированный count++, если более неудачные аутентификации с этим именем пользователя. Я использую redis для этого.

Если count >= threshold, тогда необходимо решить значение CAPTCHA перед продолжением. Показать CAPTCHA на экране входа в систему.

После успешной проверки подлинности очистите сохраненное имя пользователя в глобальном состоянии. Дайте пользователю "доверенный пользовательский агент" HMAC'd cookie, поэтому им не нужно CAPTCHA в будущем для этого имени пользователя на этом UA.

Вы можете сделать то же самое для паролей, но, вероятно, с более высоким порогом.

Если вам не нравится CAPTCHA, тогда требуйте подтверждения работы, например, заставив клиента рассчитать и представить простые коэффициенты очень большого числа.

Пока вы на нем, убедитесь, что вы используете bcrypt для хэширования своих паролей и что коэффициент затрат достаточно высок, чтобы он принял >= 250 мс для хеширования пароля. Это замедляет работу вашего сервера, но также замедляет работу злоумышленника. Избегайте хэширования, если они не передают CAPTCHA (если требуется).

Поощрять пользователей использовать длинные, сложные, запоминающиеся? паролей, так что они сложнее грубой силы.

Ответ 2

Самым простым было бы направить ваше решение с помощью поставщика CDN, такого как cloudflare (https://www.cloudflare.com/features-security), который обнаружит ботов для вас. Многие CDN предлагают это, и у облачных плат есть бесплатный тариф.

В качестве альтернативы, если вы пытаетесь сделать это самостоятельно, вы можете подсчитать количество попыток за каждое имя пользователя в своей базе данных и представить капчет на основе этого счета.

Ответ 3

Определите недействительный логин на основе IpAddress (анонимный прокси). Это недействительный номер входа в систему и время входа в систему и время, которое будет сохранено в состоянии приложения.

Создать класс InvalidLogin

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

Событие входа

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<InvalidLogin> user = null;
                if (HttpContext.Current.Application["Users"] == null) //Adding List to Application State
                {
                    user = new List<InvalidLogin>();
                }
                else
                {
                    user = (List<InvalidLogin>)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 
                    }
                }




            }
        }

Ответ 4

Если вы используете свои собственные классы проверки подлинности и авторизации, вам нужно подсчитать количество неудачных попыток входа в систему для каждого пользователя и дату и время.

Если количество попыток достигнет предела, что вы нарушите следующий процесс входа в систему с сообщением об ошибке, например: "Ваша учетная запись была заблокирована на 15 минут, повторите попытку позже".

Например. Таблица логинов называется [Logins].

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

Итак, ваш класс Login будет иметь следующие новые поля:

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

Также вам нужно сохранить какую-либо конфигурационную переменную - значение максимального количества неудачных попыток входа в систему и периода блокировки.

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

В методе signIn вы сделаете следующее (примитивный пример кода, а не prod-version):

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

Ответ 5

Вы можете приостановить учетную запись после нескольких неудачных попыток и ответить на вопросы безопасности пользователя, чтобы снова включить ее. Также не допускайте повторного использования нескольких последних паролей, и вы должны быть в безопасности.

Теперь, когда вы хотите сделать это с помощью кодирования, сохраните третье время попыток входа в систему [MaxAttemptTime] (DateTime.Now) и время для выпуска учетной записи [ReleaseTime] (скажем, через 20 минут DateTime.Now.AddMinutes(20)).

Теперь каждый раз, когда есть попытка от того же пользователя войти в систему, его следует отклонить на основе [ReleaseTime]. Reset эти счетчики на успешном входе в систему для подлинного пользователя.

Ответ 6

Единственное, что я хотел бы добавить, что другие не так, по возможности, вы не хотите предупреждать ботов о том, что они были обнаружены. если вы заблокируете их некоторым сообщением, тогда они просто отметят, что они сделали, чтобы их можно было обнаружить и настроить. если вы, например, "замечаете" их по ip, просто не позволяйте паролю, который они вводят, когда-либо достигнут успеха. они будут обмануты, думая, что у вас есть сложные пароли и т.д., и отправляйтесь в другое место, не зная наверняка, что заметили их.

Я также предлагаю хранить "попытки" в базе данных с ip. вы можете легко вернуться и просмотреть попытки, предпринятые против вашего сайта. вы можете запросить веб-журналы, но это более болезненно. Я также регистрирую успешные логины, поэтому я могу заметить, когда боты действительно возвращаются и применяют дальнейшие исследования.

Ответ 7

Если бы я делал это, я бы использовал столбец в базе данных для хранения номера попытки входа в систему и отметки времени даты для первой попытки. Затем выполните логику вокруг входа

 if(loginAttempt>5 && DateTime.Now<loginDate.AddMinute(5))
{
    //Locked out
}