Класс для борьбы со спамом в формы
Автор: Misha v.3 [01 сентября 2006]
Версия: 2.2
Тэги: Спам
Предлагаемый класс использует для защиты от спама в формы сайта несколько механизмов.
В первую очередь происходят проверки referer-ов при открытии формы и при получении данных. Вы как программист можете задать список разрешенных url, при переходе с которых класс не будет реагировать на посетителя как на спамера, пришедшего с результатов поисковиков или тупо передавшего в качестве referer ваш собственный url. Также вы можете запретить работу в случае пустого значения referer.
Во вторых, перед отображением формы генерится, сохраняется в hashfile и помещается в скрытое поле уникальный идентификатор. При приеме данных пользовательская обработка запускается лишь при совпадении пришедшего и сохраненного идентификаторов. Это гарантирует, что никто не сможет запостить данные, предварительно не загрузив форму (причем каждый выданный идентификатор имеет ограниченное время жизни). Отдельно этот механизм был применён ранее и подробно описан в примере класса antiflood.
В третьих, в класс встроен механизм, предложенный участником форума ASharky и заключающийся в том, что перед отображением форма модифицируется, и в неё добавляются избыточные поля, которые тем не менее ни в коем случае не должны быть отправлены обратно на сервер. На стороне клиента мы должны скрыть эти поля с помощью CSS (если это submit|image поля) или очистить их значения с помощью JavaScript (если это hidden поля), а роботы, которые открывают форму с сайта, заполняют её по заранее заданному шаблону и выполняют POST данных, с большой вероятностью не смогут угадать какие именно поля должны быть очищены для успешной отправки данных (тем не менее если захотят заспамить именно вас - сделают специальный алгоритм спам-роботу для вашей формы и заспамят).
В четвертых, класс проверяет, не пытаются ли ему запихнуть в form кучу полей, не упомянутых в <form/> при запросе формы и с случае обнаружения подобной активности — посылает. Однако есть возможность указать список полей, на которые класс не будет реагировать подобным образом.
В пятых, можно задать список регулярных выражений с удельными весами, с помощью которого будут проверяться все поля после отправки формы, а также порог срабатывания, и в случае, если этот порог будет превышен — процесс обработки данных не будет запущен.
И наконец класс позволяет добавлять к форме тесты Тюринга (есть пример в архиве), т.е. для того чтобы данные обрабатывались посетителю нужно будет решить определенную задачу (выполнить арифметическое вычисление, распознать картинку, выбрать правильный вариант ответа на предложенный вопрос и т.д).
В случае обнаружения спамерской активности класс не выполняет пользовательский код, а вызывает исключение, которое должно быть обработано.
Класс сам меняет последовательность настоящих и фиктивных полей в html и имеет множество настроек, позволяющих в том числе задавать количество фиктивных полей, параметры статической и динамической модификации их атрибутов, включать механизм автоматического бана спамеров и др.
Класс работает с <input type="submit|image|button" /> и в принципе должен работать с <button />, однако суровая реальность такова, что несколько <button/> не работают нормально в IE (проверял в версии 6.0).
Например посмотрите как работает этот код в IE и FF/Opera:
<form method="get">
<button type="submit" name="action" value="1">1</button>
<button type="submit" name="action" value="2">2</button>
<button type="submit" name="action" value="3">3</button>
<button type="submit" name="action" value="4">4</button>
</form>
После нажатия на любую из кнопок в IE в строке броузера можно увидеть: ?action=1&action=2&action=3&action=4. Таким образом при использовании <button /> остается лишь один вариант: с помощью JavaScript убрать избыточные кнопки или установить им атрибут disabled. Конечно установить этот атрибут фиктивным кнопкам можно и средствами класса, однако роботы, которые скачивают форму, заполняют её по шаблону и постят обратно, не настолько тупы, чтобы отправлять обратно поля с данным атрибутом.
Класс несложно подключить к уже существующим формам на сайте, т.к. для этого не требуется вызывать кучу методов в строго определённой последовательности и модифицировать html формы. В начале документа создайте объект класса:
$oAntiSpam[^AntiSpam::create[хеш с параметрами]]
$bShowForm(true)
и параметрами определите его поведение (подробнее о параметрах смотрите в находящихся в архиве примерах с комментариями или в коде класса, при этом будьте готовы к тому, что параметров много). Затем вокруг выдаваемой у вас в html формы:
<form ...>
...
</form>
добавьте:
^if($bShowForm){
^oAntiSpam.print{
<form ...>
...
</form>
}{
$exception.handled(true)
...тут добавьте код обработки exception при выводе формы,
которая произойдёт при срабатывании спам фильтра...
}
}
И наконец измените ваш существующий механизм обработки POST-а с:
^if(def $form:поле){
... ваш код обработки события ...
}
на:
^oAntiSpam.exec{
... ваш код обработки события ...
$bShowForm(false)
}{
$exception.handled(true)
...тут добавьте код обработки exception при POST-е данных,
которая произойдёт при обнаружении спам-активности или
при проверке заполненности полей...
}
Обратите внимание: вам не нужно больше вручную проверять определённость какого либо поля чтобы понять: был POST или нет, класс сам это сделает и выполнит содержимое exec лишь в случае, если произойдёт реальный POST данных и не будут выявлены признаки спам-активности.
Методы print и exec можно рассматривать как аналоги ... try. Их тело выполняется лишь при «благоприятных» условиях (для print: если не нашли признаков спамера, для exec: если идет реальный POST и также не обнаружили признаков cпамера), а в часть обработки ошибок попадаем в случае выявления спам-активности, или в случае, если внутри кода обработки вы сами вызвали исключение (throw), например при обнаружении незаполненности некоторых полей.
Скачать:
Antispam.2.2.zip
(17.08.2011
72,5 КБ)
Класс для защиты веб-форм от спама с примерами использования.