Почему блокировка (это) thread.sleep не работает с многопоточностью ASP.NET? - PullRequest
2 голосов
/ 26 июня 2010

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

bool isGoodPassword = (password == expected_password);

lock (this)
{
     if (!isGoodPassword)
           Thread.Sleep(2000);
}

Я ожидаю, что это позволит использовать все правильные пароли без остановки, но если один пользователь введет неверный пароль, другой успешный пароль другого пользователя также будет заблокирован. Однако блокировка не кажется lock между потоками ASP.NET. Не имеет смысла.

Ответы [ 4 ]

16 голосов
/ 26 июня 2010

Ну, вы еще не показали, что такое "это", но если вы находитесь в контексте страницы ... каждый запрос получит свой экземпляр страницы, не так ли?Иначе как бы у них были разные пароли?У вас будет несколько потоков, каждый из которых будет привязан к отдельному объекту.

Во многих отношениях это хорошо : вы не хотите, чтобы злоумышленники подвергали действию реальных пользователей.С другой стороны, это означает, что атакующему просто нужно сделать несколько попыток параллельно, чтобы эффективно игнорировать вашу попытку помешать ему.Как уже говорилось в других ответах, вы можете обойти это, используя один объект - но, пожалуйста, не делайте этого.Не забывайте, что новые потоки не будут создаваться до бесконечности IIS: этот подход позволит одному злоумышленнику сделать ваше приложение непригодным для всех пользователей, не только для аутентификации, но и для всего приложения ...и им даже не потребуется иметь действительный пароль.

Вместо этого вы можете рассмотреть возможность записи IP-адресов, которые не прошли проверку подлинности, и ограничить количество запросов, которые вы готовы обработать таким образом.(По общему признанию, это может иметь проблемы для некоторых пользователей, если они находятся за тем же прокси-сервером, что и злоумышленник, но это менее вероятно.) Это не остановит распределенную атаку, но это хорошее начало.

2 голосов
/ 26 июня 2010

Мои два цента: Я искал другой подход.Я не верю, что программное решение является правильным местом для предотвращения атаки отказа.В конце концов, это решение не удастся.IIS требует времени для обработки кода до точки, где он достигает кода блокировки.Код блокировки не предотвращает запросы.Это позволяет только одному пройти одновременно.Фактически он действует как очередь.

С учетом сказанного попробуйте использовать статическую переменную.

private static readonly  object _lock = new object();

...

lock (_lock)
{
     if (!isGoodPassword)
           Thread.Sleep(2000);
}
2 голосов
/ 26 июня 2010

ASP.NET выполняет каждый запрос в отдельном потоке. Если вы хотите заблокировать запросы, вы можете использовать статический объект:

public class LogOn : Page
{
    private static object _delaySync = new object();

    private void Authenticate()
    {
        lock(_delaySync)
        {
             if(password != expected_password)
             {
                 Thread.Sleep(2000);
             }
        }

    }
}

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

2 голосов
/ 26 июня 2010

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

bool isGoodPassword = (password == expected_password);

lock (this.GetType())
{
     if (!isGoodPassword)
          Thread.Sleep(2000);
}

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

Кроме того, сравнение паролей подразумевает, что вы знаете пароль пользователя, и это всегда плохая практика.Лучший подход - сохранить (соленый) хеш прохода пользователя и сравнить его с хешем ввода.Также вы можете использовать прогрессивные задержки (1-я ошибка - время ожидания 1 с, 2-я ошибка - 2 с, 3-я - 4 и т. Д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...