Правильно делать временные запреты - PullRequest
1 голос
/ 13 сентября 2009

Хорошо, у вас есть форма для входа и вы хотите забанить пользователей на 5 минут, если они неправильно введут пароль / пользователя. Пользователь может попробовать несколько раз подряд, пока его не забанят.

Таблица LOGIN_FAILS:

  • id PK, serial / auto_increment
  • ipaddress int / text / что угодно
  • добавлено DATETIME / TIMESTAMP

SQL:

SELECT IF(COUNT(id) < 3, 'false', 'true') AS is_banned FROM LOGIN_FAILS WHERE ipaddress='1.2.3.4' AND added BETWEEN (NOW() - INTERVAL '5 minutes') AND NOW();

Это можно представить как

Блокировка чека по времени: #####

Сбои: 1,2,3

Сбои устанавливаются в диапазоне времени:

Time ->
========1==2=3==========
========######==========

Теперь вы можете повторить попытку один раз подряд:

========1######=========

Теперь вы можете повторить попытку дважды:

========1==2######======

Но правильный подход - удерживать этот временной блок на 5 минут

========######==========

Теперь вы можете повторить попытку три раза подряд

========1==2=3######====
        ^^^^^^ Ignored

Но вы не хотите использовать текущее время в качестве блоков (0: 00-0: 05, 0: 05-0: 10 и т. Д.), Потому что если бан произойдет в 0:04, следующий блок проверки чека будет 0 : 05 (= бан только на 1 минуту).

Так что же нужно добавить / изменить в данном операторе SQL, чтобы пользователь всегда мог попробовать N раз подряд, а затем удерживать временный бан в течение X минут?

Редактировать

Так что-то вроде

SELECT
  IF(COUNT(id) < 3, 'false', 'true') AS is_banned
FROM 
  LOGIN_FAILS
WHERE 
  ipaddress='1.2.3.4' AND
  added 
  BETWEEN
  (
    SELECT
      MIN(added) AS min
    FROM
      LOGIN_FAILS
    WHERE
      ipaddress='1.2.3.4' AND
      added <= (NOW() - INTERVAL 5 minutes)
    ORDER BY
      added
    LIMIT 3
  )
  AND
  NOW()

Ответы [ 3 ]

2 голосов
/ 13 сентября 2009

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

$ time_for_ban_try = 10; // мин., Например

$ sql = "SELECT IF (COUNT (id) <3, 'false', 'true') AS is_banned ОТ LOGIN_FAILS WHERE ipaddress = '1.2.3.4' И добавлено МЕЖДУ (NOW () - INTERVAL $ time_for_ban_try MINUTE) И СЕЙЧАС () "; </p>

Если я ошибаюсь, пожалуйста, дайте мне знать.

1 голос
/ 13 сентября 2009

Memcache идеально подходит для такого рода вещей и принесет гораздо меньше накладных расходов (и намного меньше кода) в вашу систему, чем таблица базы данных. Вы можете подсчитать ошибки входа в систему, установив пару ключ-> значение IP -> #_ of_failures, и просто кэшировать ее столько секунд, сколько вы хотите отслеживать ошибки входа в систему. Если значение (количество сбоев) слишком велико, вы кешируете уникальное «забаненное» значение для этого IP на 5 минут.

Обратите внимание на тот факт, что бан пользователей за сбои входа в систему крайне раздражает, и если вы сделаете это, вам следует установить допустимое количество сбоев равным очень . У пользователей обычно есть набор паролей (в порядке «важности»), которые они попытаются использовать на вашем сайте, если они его забыли.

Также следует учитывать тот факт, что несколько человек могут использовать один и тот же IP-адрес (как в студенческом городке или в частной сети).

1 голос
/ 13 сентября 2009

Ваш вопрос длинный, и я признаюсь, что изо всех сил пытаюсь разгадать то, что вы спрашиваете. Я полагаю, вы спрашиваете: Если я проверю "сколько было сбоев за последние X минут?" тогда блокировка продлится только до тех пор, пока не исчезнет самый последний сбой; как мне убедиться, что это всегда длится 5 минут?

Если это то, что вы спрашиваете, то здесь достаточно простой подход: при каждом сбое входа в систему спрашивайте базу данных «сколько отказов за последние X минут?» Если их плюс один, который только что вышел из строя, равен 3 или более, то установите для столбца (скажем, locked_until) в строке базы данных пользователя значение + 5 минут.

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

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