Часто ли вам приходится сталкиваться с работой CAPTCHA-систем? Это такие системы скриптов, задающие загадки и генерирующие трудночитаемые картинки с цифрами, буквами и прочим безобразием и сверяющие потом то, что вы ввели, с эталоном. В частности, таким образом сайты обороняются от автоматизированной рассылки рекламы по форумам и гостевым, отделяя добропорядочных пользователей от спам-программ. Считается, что автоматический тест Тьюринга крайне осложняет жизнь спам-программам, поэтому CAPTCHA сейчас используется довольно широко, заставляя вглядываться в напрочь зашумленные надписи, гадая, что на этот раз имеется в виду – единичка или латинская строчная «эл».
CAPTCHA – это аббревиатура от английских слов Completely Automatic Public Turing Test to Tell Computers and Humans Apart – полностью автоматический тест Тьюринга для различения компьютеров и людей.
Иными словами, это задача, которую легко решает человек, но которую невозможно (или крайне трудно) научить решать компьютер
Но на всякий хитрый картинкогенератор рано или поздно находится своя управа, и правильный ответ найдется: либо перебором, либо разбором механизма генерации картинок, либо еще через какое-нибудь «заднее крыльцо». И преграда для автоспамеров становится лишь раздражением для посетителя ресурса. Ухватываете суть проблемы? В погоне за спамоустойчивостью удобство пользователя как-то само собой отошло на второй план. Лично мне не особо по душе лозунг «Это для вашей же безопасности», поэтому сегодня я поделюсь с вами устройством более дружелюбного для пользователя механизма.
Для начала давайте немного поразмышляем: в чем отличие программы от настоящего, живого человека?
Проследим поведение обычного пользователя. Человек открывает страницу с формой для добавления какой-либо записи (в гостевой, на форуме и так далее), видит поля (для простоты возьмем самые распространенные) «Имя», "E-mail", «Сообщение». Он вводит в эти поля информацию и нажимает кнопку «Отправить». И все, сообщение появляется там, где пользователь и планировал его добавление (в гостевой, на форуме и так далее).
Что делает спам-программа? Она загружает страницу, определяет, какие механизмы защиты использованы, и делает свое черное дело. Главное отличие программы от человека в том, что она воспринимает страницы как последовательность букв, слов, строк – среди слов она по заранее заданному алгоритму может найти ссылку на заветное «Добавить комментарий», пройти по ней и вписать пару фраз рекламы либо может найти ссылки в соответствующие поля, так же аккуратно найти на странице кнопку отсылки сообщения и эмулировать ее нажатие. Причем многие программы автоматически находят пригодные для «гнездования» сайты и добавляют их в свою базу – для повторной «кладки».
Итак, поскольку мы задались целью не проверять пользователя на распознавание цветов, цифр и навыки извлечения логарифмов, становится очевидно, что наша основная борьба развернется внутри кода страницы, который пользователю по большому счету глубоко безразличен, а для программы является основным материалом для работы.
Способов внутристраничной борьбы придумано немало, по большей части они уже все известны и помогают от совсем уж примитивных программ. Но в нашем деле лишними меры быть не могут, так что сначала вкратце пройдемся по обязательному минимуму.
Ограничение по частоте сообщений
Главное отличие программы от человека – подход к странице как к последовательности текста и тегов, тогда как человек видит конечный результат перевода страницы в визуальный образ
Самый простой инструмент. Необходимо следить, чтобы с одного и того же IP-адреса не было по десятку сообщений в минуту. Ясно, что вряд ли человек с такой частотой будет высказывать какие-то умные мысли. Этот прием, конечно, толком не избавляет от спама, но сокращает его поток. Главное тут – правильно подобрать интервал: и большой плохо, и короткий нехорошо. По собственному опыту минуты три – в самый раз.
Блокирование сообщений по ключевым словам
Тоже довольно простой фильтр: не пропускаются до публикации сообщения, имеющие среди текста слова, которых точно не будет содержать добропорядочный текст. Заодно можно отфильтровывать не только рекламу, но и мат.
Замена символов двойниками
Случайная замена на странице букв на схожие по написанию символы (для человека все равно, а для разбора и поиска по шаблону – помеха). При этом в ссылках, ведущих на добавление комментариев или на регистрацию, буквы меняются на схожие по написанию, но имеющие другой код. Например, русские «а», «о», «р» на английские «a», «o» и «p» соответственно. Это немного усложняет поиск потенциальных сайтов-жертв.
Изменение имен полей ввода
Многие программы ищут в странице поля ввода со стандартными именами: «name», «user», «nick», «email», «mail» и так далее. Чтобы доставить программе некоторое неудобство, лучше называть поля как-нибудь нестандартно. Например, «kndfjero».
Замена надписей картинками с текстом
Если реализован предыдущий шаг, то есть шанс, что программа не сдастся, не найдя привычных имен полей, а попытается проанализировать находящиеся рядом надписи, пытаясь выяснить, к чему какое поле относится. Смена поясняющих надписей на картинки с текстом сильно усложняет эту задачу в плане решения на программном уровне, а уж пиктограммы и вовсе делают ее практически невыполнимой. Визуально, с точки зрения пользователя, на странице ничего не меняется: какая ему разница, как набран текст на сайте, картинкой или текстом? С другой стороны, достаточно спамеру-человеку один раз посетить такую страницу и «врукопашную» посмотреть, что где находится, – и все, программе уже задан шаблон для этой страницы, она знает, куда что писать и куда нажимать для отправки.
Встраивание полей-приманок
Раз программа ищет поля «name», «message» и тому подобные, почему бы не «обрадовать» ее этими полями? Это сделать довольно просто, например, так:
Имя:
<input type=text name=name style="visibility: hidden; width: 1px;" value="">
<input type=text name=nlconpiqo value=""><br>
E-mail:
<input type=text name=email style="visibility: hidden; width: 1px;" value="">
<input type=text name=ummsklcqu value=""><br>
При отображении такие поля не видны, а программа их находит и обрабатывает. От особенно умных программ "visibility: hidden" прячется в CSS:
<style type="text/css">
input.foul {
visibility: hidden;
width: 1px;
height: 1px;
}
</style>
...
Имя:
<input type=text name=name class=foul value="">
<input type=text name=nlconpiqo value=""><br>
E-mail:
<input type=text name=email class=foul value="">
<input type=text name=ummsklcqu value=""><br>
Построение формы с помощью JavaScript
Этот метод делает анализ формы еще более сложным: программе необходимо найти и выполнить код JavaScript, чтобы получить форму, которую следует заполнить:
<div id=mform> Включите, пожалуйста, поддержку JavaScript в браузере </div>
...
<script language=javascript>
myform=document.getElementById("mform");
mystr="<form method=\"post\" name=\"som";
mystr=mystr+"eform\" action=\"somescript.php\">И";
mystr=mystr+"мя: <input type=text name=ni";
mystr=mystr+"ck value=\"\"><br>E-ma";
mystr=mystr+"il: <input type=text name=ema";
mystr=mystr+"il value=\"\"><br>Сообщение: <texta";
mystr=mystr+"rea cols=35 rows=8 name=ms";
mystr=mystr+"g></textarea><br><input type=bu";
mystr=mystr+"tton value=\"отправить\" onclick=\"somef";
mystr=mystr+"orm.submit()\"><br></form>";
myform.innerHTML=mystr;
</script>
Наличие механизмов обучения и делает автоспамеров особенно въедливыми: один раз программе показали, как надо действовать при данной ситуации, она запомнила, и все – разгребай, хозяин, спам на форуме. Значит, надо сделать так, чтобы страница каждый раз была разной, верно? Отлично, тогда переходим к следующим, более изощренным методам.
Генерирование случайных имен полей ввода
Это просто усовершенствованный метод изменения имен полей ввода: имена изменяются не один раз (при написании скрипта), а при каждом вызове страницы. Тут есть одна тонкость: поскольку имена раздаются динамически, надо как-то известить получающий данные скрипт, какая переменная за что отвечает. Например, ввести дополнительное скрытое поле, в которое записать шифровку, в которой указать, какие поля обрабатываются:
<form method="post" name="jdfjvb" action="somescript.php">
Имя: <input type=text name=nlconpiqo value=""><br>
E-mail: <input type=text name=ummsklcqu value=""><br>
Сообщение: <textarea cols=35 rows=8 name=thtqnrnee></textarea><br>
<input type=button value="отправить" onclick="jdfjvb.submit()"><br>
<input type=hidden name=temp value="piqonlconbnhrshelcquummskrneethtqn">
</form>
В somescript.php происходит разбор переменной-шифровки temp с именами и выуживание из переданных данных нужной информации:
$war = decrypt_string($temp);
$name = trim($_POST[$war[0]]);
$email = trim($_POST[$war[1]]);
$message = trim($_POST[$war[2]]);
Функция decrypt_string отвечает за расшифровку переданных данных и не ограничена ничем, кроме вашей фантазии. Алгоритм шифрования можно в любой момент изменить, например, если спамер просто использует единожды загруженную страницу для отправки повторных сообщений.
Генерирование принимающего скрипта
Усложняем предыдущий случай: кроме случайных имен будем создавать на диске и принимающий скрипт:
<form method="post" name="jdfjvb" action="shebnhr.php">
Имя: <input type=text name=nlconpiqo value=""><br>
E-mail: <input type=text name=ummsklcqu value=""><br>
Сообщение: <textarea cols=35 rows=8 name=thtqnrnee></textarea><br>
<input type=button value="отправить" onclick="jdfjvb.submit()"><br>
<input type=hidden name=temp value="piqonlconbnhrshelcquummskrneethtqn">
</form>
На диске, соответственно, создается shebnhr.php – на этот раз введенные данные отправятся на обработку этому файлу. Таким образом, можно иногда менять поля «Имя», "E-mail" и «Сообщение» местами (что нанесет ущерб удобству пользователя не в пример меньше, чем корявые буквы на рисунке, но окончательно собьет с толку программу), менять механизм шифрования на лету – ведь принимающая часть генерируется специально под данные имена полей, под данную форму. Переданная запись сохраняется в гостевой, а после принимающий скрипт стирает сам себя. Соответственно, использовать страницу для отправки данных вторично невозможно чисто физически: файла, к которому обращались в первый раз, давно нет. Конечно, не знаю, насколько оправданно применение решения для сайта в 3000 уникальных посетителей и 600-700 сообщений в день, ибо получается нагрузка на жесткий диск из-за создания и стирания файлов.
Обработка по билетам
Вместо формирования индивидуального принимающего скрипта для каждой попытки добавления комментария можно использовать своеобразные кодовые билеты: в форме среди прочих полей указывается скрытое поле с уникальным билетом – кодовой строкой, которая также внесена в базу билетов. После добавления комментария билет удаляется из базы и повторная отправка данных не пройдет – билет уже отработал, его нет в базе.
Против «ручных дел мастеров» адекватной мерой является только анализ контекста
Увы, против спамеров, вбивающих объявления вручную, противоядий вовсе нет (кроме разве что фильтрования сообщений по содержимому). С другой стороны, целью этой статьи не было выведение универсального оружия против спама. Целью было показать, что тест Тьюринга – не панацея, а иногда – только причина раздражения. И что в большинстве случаев можно запросто обойтись без него, не заставляя пользователя делать лишние операции. Достаточно только хотя бы немного изменить, придать индивидуальности файлам – из-за одного-единственного сайта переделывать ориентированную на типовые решения и распространенные CMS спам-программу никто не будет.
Ссылки по теме
Статья получена: hostinfo.ru