parser

Класс для борьбы со спамом в формы

Автор: 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 КБ)
Класс для защиты веб-форм от спама с примерами использования.