|
|
|
| Здраствуйте, я работаю сейчас над созданием блока кода, который должен будет пользователя "сдерживать" при особо активных действиях. Помогите спроектировать эти действия хотя бы с логической части. У меня есть некоторые размышления, но, боюсь, есть намного более простое решение проблемы, о котором я не знаю.
Итак. У меня алгоритм следующий. Создаю табличку `activity` с полями `id` (или `ip`), `name`, `last_activity`, `activity_check`. Представим такую ситуацию. Пользователь вызывает форму для авторизации, набирает там свои идентификационные данные. После отправки формуляра происходит следущее: в таблице `activity` ищется пользователь с данным `ip`, если такового не существует, мы авторизируем пошльзователя, и если авторизация пройдена. создаем запись, куда помещаем эти данные: ip, name, time() и 0 в поле `activity_check`, потому что пользователь авторизируется, а если авторизация не прошла, то создается аналогичная запись без `name`. Если же после отправки формуляра мы находим в `activity` пользователя с данным `ip`, то мы не создаем новой записи, а обновляем текущую. Но сначала мы должны узнать значение поля `activity_checks` и если на данный момент `activity_checks` >= 3 мы проверяем, с момента последней активности прошло 15 минут или нет. Если да - прописываем в `activity_checks` ноль, если нет - блокируем пользователя от любой активности на форуме. Как происходит обновление: мы узнаем, какое у пользователя с `activity_check` и `last_activity`. Если activity_checks менее 3х (else условие для предыдущей развилки), то если (time() - $row->last_activity <= 60), т.е. с момента последней активности прошло менее минуты, то мы увеличиваем значение поля `activity_checks` на единицу, иначе прописываем туда ноль.
Итак, как бы я коряво не объяснил, думаю, хоть кто-то что-то понял. И по сему вопрос, как мне сделать это быстрее, надежнее и проще? З.Ы. эта таблица будет также использоваться для вывода пользователей "на сайте" | |
|
|
|
|
|
|
|
для: Inque
(21.05.2007 в 10:45)
| | Вы же всё достаточно подробно расписали, осталось только алгоритм на php переложить.
Единственный вопрос - Вы вправду считаете, что одновременно с одного IP может прийти не более одного пользователя? | |
|
|
|
|
|
|
|
для: Trianon
(21.05.2007 в 10:57)
| | Вы знаете, я долго думал над этим, но пока мне не приходит более умной идентификации пользователя в таблице, нежели по `ip`. Я хотел все делать через `id` пользователя, но подумал о том, что хорошо бы ограничить попытки отправки формы авторизации, дабы защитить форумчан от брута пароля... Я знаю, что с одного ip может сидеть несколько людей, даже десятки, особенно в моем случае (форум для мобильных устройств, у билайна на 1м айпи несколько десятков пользователей), но пока не придумал ничего другого, служащего для данной ситуации primary key'ем :). Если у вас есть мысли по оптимизации данного скриптика, пожалуйста, советуйте, я с PHP только с января. | |
|
|
|
|
|
|
|
для: Inque
(21.05.2007 в 12:28)
| | собственно, три мысли приходят в голову.
1. ставить клиенту Cookie. Тех, кто установку cookies игнорирует - даже не пытаться авторизовывать более чем на один http-запрос.
2. учитывать user-agent
3. блокировать логин, а не ip | |
|
|
|
|
|
|
|
для: Trianon
(21.05.2007 в 13:06)
| | По вашему предложению:
1. Так надоели эти куки - жуть, у меня они еще и для идентификации пользователя на форуме служат, я, кстати, тему создавал :)
2. Все будут сидеть с Opera Mini - сайт под мобильники
3. При отправке формы авторизации еще нет логина... А может не прогонять через антифлуд отправку формы регистрации/авторизации, зачем лишний гемор? Но тогда как же брут - подбор пароля... | |
|
|
|
|
|
|
|
для: Inque
(28.05.2007 в 10:43)
| | 1. --
2. У Оперы свои поля user-agent есть.
3. Вы сказали, что реализуете антифлуд, а не защиту от повторных регистраций.
Последняя делается строго по капче. | |
|
|
|
|
|
|
|
для: Trianon
(28.05.2007 в 11:07)
| | !Конечно! Однако я хотел убить 2х зайцев одним выстрелом! А антифлуд, конечно же, буду по id'шнику реализовывать... Пожалуйста, будьте так добры, объясните, что значит "по капче" и что, у opera mini разные юзер_агенты могут быть? В зависимости от версии что ли? | |
|
|
|
|
|
|
|
для: Inque
(28.05.2007 в 16:33)
| | "по капче" - сцылко нумер раз, нумер дыва
> разные юзер_агенты могут быть?
У оперы наверное, тоже могут быть разные, но в любом случае, люди-то к Вам будут ходить не только с оперы. Чуть ли не у каждого телефона свой юзер агент (мне почему-то так кажется, могу ошибаться). Не надо забывать про всякие КПК и т.д.
Так что нужно просто запомнить последний ЮА пользователя.. И вместе с (1)(3) использовать. | |
|
|
|
|
|
|
|
для: kasmanaft
(28.05.2007 в 17:14)
| | Понял, спасибо, но вообще-то это несколько ущербно для трафика... Ну буду думать ;) | |
|
|
|
|
|
|
|
для: Inque
(06.06.2007 в 23:19)
| | С ип для мобильных устройств есть 2 больших НО:
1. некоторые операторы предоставляют идинаковые ип разным клиентам (бывает что половина города на одном ип)
2. есть операторы, которые меняют ип клиента при КАЖДОМ запросе, например так
208.131.186.18
208.131.186.9
208.131.186.7
С оперой мини на первый взгляд все мудрено, но в итоге она передает реальный ип и юзер агент (хотя агент можно изменить прямо с нее, так что на него вообще полагаться не стоит).
Посоветовать что-либо универсальное тут крайне сложно, наверно, лучше отказаться от затеи с ип и использовать нечто другое, например ид... | |
|
|
|
|
|
|
|
для: Disable
(07.06.2007 в 00:42)
| | Да, наверное... Вобщем, я сегодня, надеюсь доделаю эту схему и выложу код сюда :) | |
|
|
|
|
|
|
|
для: Inque
(08.06.2007 в 14:51)
| | Да, кстати. Есть тут такая тема искать пользователя в users.php так, чтобы можно было ссылку представить ввиде:
http://somesite.ru/users.php?Inque
а не так
http://somesite.ru/users.php?name=Inque
Как мне это реализовать? Очень интересно, тему не хочу новую создавать :) | |
|
|
|
|
|
|
|
для: Disable
(07.06.2007 в 00:42)
| | Нужно разделять написание кода, для обеспечения удобной работы легковесных пользователей и написание кода, который бы работал при попытках создать серверу искусственные сложности (типа руками переделать user-agent, отрубить кукисы и т.п.) . Последних код может просто игнорировать. | |
|
|
|
|
|
|
|
для: Trianon
(16.06.2007 в 21:41)
| | А по моему последнему вопросу ничего не скажешь? :) | |
|
|
|
|
|
|
|
для: Inque
(17.06.2007 в 00:05)
| | echo $_SERVER['QUERY_STRING'];
[поправлено модератором] | |
|
|
|
|
|
|
|
для: Trianon
(17.06.2007 в 02:27)
| | Спасибо. Я потом по этой строке в базе буду искать. Мне надо будет ее обрабатывать вот этим?
function get_safe_string ($some_string) {
$safe_string = trim($some_string); // Удаляем пробельные символы
$safe_string = htmlspecialchars($safe_string, ENT_QUOTES); // Конвертируем спецсимволы в строке в HTML-представление.
$safe_string = stripslashes($safe_string); // Удаляем обратные слеши
return $safe_string;
}
|
| |
|
|
|
|
|
|
|
для: Inque
(17.06.2007 в 13:53)
| | Вот этим я бы не пожелал обрабатывать никаких данных. Разве что врагу.
Особенно захватывает дух удаление экранирующих слэшей уже после преобразования (кавычек например) в html-эквиваленты.
И вроде как комментарии стоят.... Значит Вы знаете, что делаете. Тогда почему опять такой компот?
См. задачу 21. В разделе "задачи". | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 10:59)
| |
function get_safe_string ($some_string) {
$safe_string = trim($some_string); // Удаляем пробельные символы
$safe_string = stripslashes($safe_string); // Удаляем обратные слеши
$safe_string = htmlspecialchars($safe_string, ENT_QUOTES); // Конвертируем спецсимволы в строке в HTML-представление.
return $safe_string;
}
|
Так проблема решена? Меня больше волнует то, надо ли эту строку прогонять через данный фильтр - строка будет использована для запросов в БД. | |
|
|
|
|
|
|
|
для: Inque
(20.06.2007 в 18:23)
| | Дело в том, что stripslashes() не решает проблему кавычек и нарушения синтаксиса... если вы хотите защититься от SQL-инъекции лучше использовать конструкцию
<?php
if (!get_magic_quotes_gpc())
{
$some_string = mysql_escape_string($some_string);
}
?>
|
htmlspecialchars(), особенно с ENT_QUOTES в принципе не позволит манипулировать злоумышленику с кавычками, однако хранить обработанный этой функцией текст не удобно - так как возможно потребуется его отредактировать. Обычно htmlspecialchars() используют непосредственно перед выводом в окно браузера. | |
|
|
|
|
|
|
|
для: cheops
(21.06.2007 в 10:53)
| |
if (!get_magic_quotes_gpc()) {...}
|
Что проверяет данная конструкция? Впервые такое вижу. И еще, нельзя ли просто этот код впихнуть в мою функцию? Я стремлюсь к тому, чтобы сделать что-то универсальное и не писать определенную последовательность фильтрации каждый раз, когда я загоняю данные в бд или вытаскиваю из нее что-то. Вобщем, я понял, что делаю что-то не так, а по сему прошу, будьте добры, напишите, чем бы вы фильтровали все данные на входе в БД и чем бы на выходе преобразовывали в нормальное представление. Это форум, очень важно, чтобы вероятность дыры в инъекциях и не только сводилась к минимуму. | |
|
|
|
|
|
|
|
для: Inque
(21.06.2007 в 12:09)
| | Вот в этой теме я как-то сделал попытку раскрыть суть метаморфоза строк на пути от формы ввода к браузеру через БД.
Возможно, Вас заинтересует.
http://softtime.ru/forum/read.php?id_forum=3&id_theme=14355 | |
|
|
|
|
|
|
|
для: Inque
(21.06.2007 в 12:09)
| | Данная конструкция определяет включены или отключены магические кавычки - автоматическое экранирование спец-символов в POST-, GET-, COOKIE- данных - они могут быть включены на сервере, а могут быть отключены. Если включены - экранировать ничего не нужно - об этом заботиться сам сервер, если отключены - нужно. Конструкция get_magic_quotes_gpc() и позволяет добиться универсальности при обработке текстовых значений, которые заключаются в кавычки перед помещением в базу данных. Все числовые значения, которые в кавычки, как правило, не помещаются проверяются либо при помощи спец-функций PHP (например, intval()), либо при помощи регулярных выражений.
PS Вы можете ориентироваться на исходные коды этого форума в разделе downloads (все коды тщательно комментированы на русском языке) - в нём защита от SQL-инъекций вылизана.
PPS Функции stripslashes() вообще не должна использоваться в обработке текста перед помещением в базу данных. | |
|
|
|
|
|
|
|
для: cheops
(22.06.2007 в 12:06)
| | >Если включены - экранировать ничего не нужно - об этом заботиться сам сервер,
Это утверждение как минимум неполное.
Если данные, помещаемые в запрос, взялись не из GET POST COOKIE или REQUEST ,
а из любого другого источника - например,
из загруженного пользователем файла
из файла находящегося на сервере, или полученного по FTP
из сокета, curl , imap и других методов получения чужих данных
и так далее!!!!
=-то экранирование потребуется.
Именно поэтому легче считать, что получение параметров и формирование запросов - вещи друг с другом несвязанные. И стрипслэшить (только если надо) параметры ввода php . И эскейпить (в любых ситуациях) параметры запросов SQL. Даже если кажется, что мы заставляем делать php двойную работу.
Именно поэтому этот кошмар (magic quotes) из php6 выкинут. | |
|
|
|
|
|
|
|
для: Inque
(21.05.2007 в 10:45)
| | Cookeis ничего не дают, я например, кода пишу ботов никогда не держу ненужные Cookies.
А поступал я вот как для антифлуда: у меня есть лимит --- пятьдесят модификационных действий в 15 минут с одного IP и 150 модификаций в 30 минут из одной подсети (храню модификации в таблице MySQL), как только лимит превышен, если это с одного IP, то полностью баню его (при этом если в одной подсети более четырёх забаненных IP --- баниться подсеть, об этом позже), а все действия отменяю (у меня был хороший механизм для отмены модификаций). Затем, когда просматриваю базу забаненых пользователей, смотрю, действительно ли он флудер, если произошла ошибка, то извиняюсь и возвращаю всё обратно.
Когда блокируется подсеть, то из неё запрещаются только модификации, а просмотр разрешается. Кроме того, если юзер --- не флудер, а его подсеть заблокирована, то я выдаю ему доверительный аккаунт (на странице написано "ваша подсеть блокирована, для получения доступа пишите админу") --- то есть аккаунт, с которого он может заходить из заблокированной подсети.
И ещё обязательно забаньте сразу все IP всех проксей, какие сможете найти в интернете.
Ну, а если вам нужно всего лишь сдержать, то можете установить таймаут на модификации (например, не более одной в пятнадцать секунд, не более пятнадцати в 15 минут с одного IP, я думаю, это будет вполне разумно, однако, когда будет много посетителей, это число нужно увеличить, чтобы при попадании двух пользователей с одного IP не было лишних недоразумений)
Кроме того на большинство форм я поставил картинку, защищающую от ботов. | |
|
|
|
|