Борьба со спамом в комментариях

Недавно у меня на «Вотсоуэвере» стали спамить в комментариях. До этого у меня такой проблемы не было — от спама спасал запрет на комментирование старых заметок (пока роботы успевали найти заметки, к ним уже закрывались комментарии).

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

Самое первое, что я захотел проверить — это разница во времени между моментом получения роботом формы и отправкой комментария. Я думал, что если это делается подряд, то это по-любому спам, ведь живому человеку нужно время, чтобы что-то написать. Оказалось, «умный» робот ждёт 5 секунд перед отправкой формы — это довольно много, за это время человек может вставить комментарий, написанный в Ворде в соседнем окне. Следовательно, таким образом отрубить спам не получится.

Я обнаружил, что все айпи-адреса, с которых был спам, есть в базе на сайте stopforumspam.com, так что можно иметь под рукой эту базу, и считать спамом все комментарии с этих адресов. Но ведь спам может прийти и с адреса, который вчера принадлежал зомби с Виндоусом Экс-пи, а сегодня принадлежит безобидному Маку.

Получается, что подозреваемый в спаме комментарий нельзя просто отметать. Может быть, как раз в таком случае показывать капчу, типа «наш глупый компьютер решил, что вы робот, но вы введите капчу, чтобы переубедить его». Тогда нужно быть уверенным, что такие случаи будут крайне редки.

Следующее над чем я думаю — это использовать Джаваскрипт, который бы делал что-то хитрое в форме, чего бы не смог сделать робот. Но я пока не знаю, вдруг роботы и Джаваскрипт выполнять умеют?

Если у вас есть какой-то опыт в этой области, поделитесь, пожалуйста.

Дальше
47 комментариев
Артем Шитов 2009

Отправлять данные не через сабмит формы?

Илья Бирман 2009

Это как?

Артем Шитов 2009

Эмулировать его. Например, сделать форму без экшна, но яваскриптом перехватывать горячие клавиши и нажатие кнопки. В этот момент каким-нибудь аяксом данные отправляются на сервер.

Замороченно слишком, правда.

Илья Бирман 2009

И обязательно не заработает в Опере :-)

Артем Шитов 2009

Она такая, к ней подход нужен :-)

Олег Горбунов 2009

Есть еще метод «honeypot», когда делается скрытое поле ввода, а атрибутом name=«email» например, а настоящее поле имеет какое нибудь бессмысленное значение, боты заполняют скрытое поле, которое человек заполнять не должен, потому что оно скрытое. Т. е. если в скрытом поле что то есть, значит, это бот. =)

Илья Бирман 2009

Спасибо.

Oleg Andreev 2009

+1 к honeypot. Очень эффективно работает против тупых универсальных роботов.

Илья Бирман 2009

Скрытость при этом мы обеспечиваем ЦССом, а не ХТМЛом, да?

Oleg Andreev 2009

Конечно. Самые параноидальные люди на каждый запрос генерируют несколько полей и делают видимым случайное из них. Но, по-моему, это необязательно.

Я бы попробовал спрятать поле в цсс так, чтоб тупой робот не мог догадаться, что оно невидимое (display:none или margin/left слишком большой). Например, поместить его где-нить внизу страницы и покрасить белой краской. Или накрыть сверху какой-нибудь фанеркой.

Антон Вернигор 2009

Сам таким не пользовался, но читал о способе, когда потенциально спамерскими считаются комментарии, содержащие, например, больше 3-х ссылок. Но тут большая вероятность «ложного срабатывания».
Вот здесь перечисляются некоторые способы защиты от спама без капчи: http://habrahabr.ru/blogs/webdev/50328/
Но лично мне наиболее симпатичен способ со скрытым полем.

Илья Бирман 2009

Я обращал внимание не то, что спамеры любят ставить несколько одинаковых ссылок разными способами (просто урл, в ахрефе, в бб-коде и т. д.), в надежде, что сработает хоть что-то.

Роман Парпалак 2009

Вполне можно сделать что-то хитрое на JS.

У меня, например, есть дополнительное поле, в которое нужно ввести сумму или разность двух чисел. Если JS включен, оно автоматически заполняется и скрывается от пользователей. После того, как я сделал такую систему, ни один робот не оставил спамерский комментарий.

Илья, надеюсь, ты теперь включишь комментарии к старым заметкам? Потому что отключать комментарии из соображений борьбы со спамом — это, мягко говоря, неправильное решение.

Илья Бирман 2009

Комментарии к старым заметкам я не включу.

То, что отключение комментариев к старым заметкам, борется с большой частью спама — это приятный побочный эффект, но не смысл отключения.

Олег Горбунов 2009

Можно скрывать ЦССом, а diaplay:none задавать не напрямую, а по наследству передать.

Роман Парпалак 2009

А в чем же смысл, если не секрет?

Илья Бирман 2009

Комментарии к заметке, написанной год назад, с текстом «да это уже полгода назад все знали!» я читать не хочу. А в чём проблема-то, что, очень хочется старьё прокомментировать? :-)

Артём Курапов 2009

Просто скрытое поле в которое я вбиваю нужное значение через js.

Раньше делал как наверху Oleg Andreev написал с десятью полями со случайными названиями и случайным позиционированием правильного textarea-поля и при заполнении неправильного автобан. Слишком сложно было, поэтому упростил. Отсекает хорошо

Илья Бирман 2009

А кому было сложно? Если уже напрограммировано и работало, то я не понимаю, зачем было упрощать работу машине. Может, что-то всё-таки не работало? :-)

А что если зайти без Джаваскрипта?

Роман Парпалак 2009

Иногда хочется.
Хотя бы сообщить о грамматической ошибке, например.

Илья Бирман 2009

А что мешает по почте написать?

Роман Парпалак 2009

Больше времени займет. Энтузиазма не хватает.

Артём Курапов 2009

Сложно в поддержке кода. Я люблю чистый и простой код. А там такой кусок был для генерации, хранения в сессии, проверке. А если процент отсечения тот же то проще — лучше. Работать работало, просто кроме этой защиты у меня ещё и древовидное комментирование и интеграция с фейсбуком..

Без JS будет поле с неправильным значением и сообщение о том что JS надо включить.

Павел Гришин 2009

%%<noscript> Анти-бот. Введите название планеты на которой мы живем:<br>
<INPUT type=«text» class=«txt» id=«ab208» name=«ab» value=»» tabindex=«9«>
</noscript>
<script>document.write(’<INPUT type=«text» class=«message» id=«ab208» name=«ab» value=«»>’);</script>
<script>document.getElementById(«ab208»).value = «з» + «е» + «м» + «ля»; </script>%%

«земля» вообще статичное слово, но можно сделать табличку ключ — слово и использовать ее.
спасает против автоматического спама на 100%, для пользователя абсолютно прозрачно.

BOLK 2009

Роботы умеют JS. Есть публичные API, которые позволяют работать со спамом в комментах.

Сергей Цепелев 2009

Все гениальное — просто) От спамерских комментариев, вот уже полтора года, меня спасает простой div в котором к названию класса привязывается значение, т. е. например по-умолчанию имеем value=0, а при нажатии на прямоугольник получаем value=1 и коммент проходит.

Илья Бирман 2009

Ничего не понял.

A!e% 2009

О, спасибо за горшочек, это отличная идея. Я вот тоже для тачдева думаю, что бы сделать. Пока там народу нет — и спама нет, но по jDnevik’у знаю, что будет, и очень много.

Правда, на тачдеве регистрация, это немного спасёт. Но все-равно нужна защита.

Arseny Sokolnikov 2009

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

Инкогнито 2009

Есть не очень разумный для стендэлон-блога способ, который сильно привязан к аяксу — при вводе текста в поле на сервер отправляется запрос (при вводе любого символа), соответственно при удалении тоже. На сервере стоит счетчик сообщений и смотрит сколько набрали, сколько удалили:не совпадает — робот, иди, гуляй.
Хотя, как мне кажется, уж лучше капча.

Александр Попов 2009

Алексей Новиков предложил свой способ борьбы со спамом: http://blog.micromarketing.ru/uncategorised/spammers-suck/
Как правило цель спама — вставить ссылку. Его метод заключается в том, чтобы определить ссылку в комментарии и проверить ее наличие в «черном списке».
Существует плагин для Wordpress, собирающий черный список со всех блогов, установивших этот плагин.
Стоит спам-ссылке однажды засветиться, как она попадает в черный список, и комментарии с такой ссылкой удаляются.

Vladimir Klimontovich 2009

http://akismet.com/ не подойдет?

Андрей Бородийчук 2009

Простой и надежный способ. Делаем любой подгружаемый файл (css, яваскрипт, картинку, favicon) отдаваемым через PHP, и при загрузке этой картинки усталнавливаем флажок в сессии.

При обработке формы проверяем наличие этого флажка. Если он есть — значит доверяем. Если его нет, значит не доверяем.

Илья Бирман 2009

Красиво!

Александр Шевляков 2009

Андрей Бородийчук, а что мешает боту сделать обращение к этому файлу? (при условии, что бот умеет работать с куками: принимать и передавать идентификатор сессии)

Максим Чусовлянов 2009

Я делаю во первых токен, некоторое длинное число, сохраняю его в сессию и в форме указываю хидден параметром, а на сервере потом сравниваю их и если не совпало то к чертям.

Андрей Бородийчук 2009

Александр, я думаю если целенаправленно кто-то станет писать спамилку для блога, то ничего из вышеперечисленного помехой не станет. А от большинства готовых или случайно забредших сюда ботов — вполне.

Максим Чусовлянов 2009

А во вторых делаю хидден поле, без значения, и скрываю его средствами CSS’а. И если приходит не пустой то тоже его выкидываю.

Сергей Цепелев 2009

2Илья Бирман
Я плохо изъяснился) Вот пример такого плагина для WordPress http://tsepelev.ru/files/captcha.phps

Илья Бирман 2009

Текст «если вы человек» сможет прочитать только человек. Это делает его бредовым :-) Когда я говорю «без капчи», я имею в виду без испытаний для человека, а не с упрощённым испытанием для человека.

Георгий Тудоси 2009

Honeypot — хорошо, только, боюсь, CSS тоже скоро парсить начнут.
Javascript — плохо: у некоторых параноиков вроде меня он по умолчанию отключен. Кроме того, браузеры для всяких мелких устройств его в принципе плохо поддерживают.

Вообще, чем менее популярна технология защиты, тем она более эффективна при прочих равных. Никто не будет затачивать боты ради десятка сайтов, даже если для этого надо одну строчку кода написать. И, наоборот, будут писать сотни и тысячи строк, если это поможет «окучить» миллионы ресурсов.

m4rr 2009

Есть класс для борьбы со спамом в формы на Парсере, но с описанием: http://www.parser.ru/examples/antispam/
На форуме этого сайта, похоже, именно он и работает.

Kildor 2009

Дурная идея:
Отправлять форму по нажатию на <input type=’image’ />, а на сервере проверять — придут-нет .x|.y значения. Для роботов — фальшивый input[type=«submit»].
Минусы для тех людей кто любит нажимать Enter в обычных текстовых инпутах, и неработающий CtrlEnter (обходится через js, который всё равно нужен для работы этого хоткея).

С другой стороны, можно связать с honeypot (наконец-то узнал, как оно называется), и взвешивать каждый комментарий.

Янис Прасол 2009

Нужно отслеживать перемещение мыши и нажатие клавиш на клавиатуре. Это отсеет даже тех, кто использует браузерный движок для спама.
Но, конечно, если решат спамить именно вас, то это не спасет, впрочем, как и самая сложна капча.

Эдзо Хогусава 2009

Может использовать события, которые может генерировать только человек (да, джаваскриптом)?
На mouseenter формы (и/или получение фокуса важного поля) писать в скрытое поле координаты мыши с event-а (и/или offset координаты on Scroll страницы). На сервере смотрим, изменилось ли значение скрытого поля.

Эдзо Хогусава 2009

Пардон на повтор, пропустил комментарий Яниса. (вот что бывает, если открывать страницу перед ужином, а комментировать после)

Андрей Шитов 2009

Очень хочу спать, поэтому могу глупость сказать:
Имеем форму для отправки комментария с левым action=»».
Добавляем кнопку, желательно, чтобы в DOM она была подальше от формы. По нажатии на кнопку аяксом получаем валидный урл для отправки формы, возможно, параллельно создаём идентификатор, который потом форма должна будет передать на сервер, и делаем form.submit().

Способ можно совместить с honeypot.

Минус способа в том, что, для большей устойчивости желательно избежать перемещения инпута к форме средствами JS, а сделать это на чистом CSS. В данном блоге эта проблема не стоит, а вот на хабре одним лишь CSS не обойтись.

Если непонятно выразился, скажите. Высплюсь, сформулирую по-человечески :)

BOLK 2009

Илья, хорошие боты сейчас делаются на основе браузеров. Так что всё, что будет работать в браузере, будет работать и в боте. Так что выбирай: API для сбора спама (например, Akismet), попытка обмануть универсальные боты (разные скрытые поля, не работает, если бота затачивают под сайт, но в случае whatsoever.ru это вряд ли), различные проверки на человека (CAPTCHA, просьба тыкнуть куда-то мышкой и прочие инструкции) или премодерация всего, что содержит ссылку (можно строже — латинские буквы).

Хорошие боты хорошо эмулируют человека, умеют даже «печатать» с задержками и ошибками, и хаотично шевелить мышкой.

Павел Урусов 2009

На самом деле в капче как таковой ничего плохого нет, на мой взгляд. Другое дело, что «порой усердие превозмогает и рассудок» — в результате на свет появляются капчи с рваным разноцветным фоном и перекрученными буковками, написанными бледно-розовым по светло-сиреневому.

У меня на сайте используется «арифметическая» капча — человеку предлагают сложить два числа и ввести ответ в поле. Достаточно эффективно (спам появляется примерно раз в месяц) и при этом никого не напрягает.

Олег Горбунов 2009

Так «горшочек» чем хорош — не вызывает диссонанс с опытом у пользователя, и работает во максимальном числе случаев. А все хитрые пляски с JS... как то это неправильно, мне кажется.

Сергій Соляник 2009

Боты обрабатывают и джаваскрипт, и флеш, и вообще всё, что делают браузеры и люди в них. Мне сильно помогает akismet.

segafredo 2009

Без Javascript: пишем рядом с формой задание пользователю, например: «поставь две точки в конце», или «вверни дефис в начале», тем самым избавляемся от двух основных бед капчи — неудобочитаемого текста и необходимости тыкать в обособленное поле ввода.

С Javascript: несколько форм, одну (кнопка скрыта) заполняем, другая имеет видимую кнопку. Бот отправляет ту же форму, которую заполняет. Можно разместить формы одну над другой и переключать z-index. Защита от парсинга CSS делается выставлением атрибутов после загрузки страницы, корректный набор берем с сервака аяксом.

segafredo 2009

А, забыл сказать: каждая кнопка отправляет javascript’ом <i>заполненную</i> форму.

О. Миляев 2009

Павел Гришин 17 ноября 2009, 14:29

В данном случает выглядит нехорошим брать по id сразу после добавления (в некоторых браузерах существует вероятность что в DOM элемент ещё не попал). Лечится 100% через onload для body и (не знаю с какой вероятность, но у меня ни разу не обламывалось) через просто setTimeout миллисекунд на 100.

Кстати, если при посылке тест не пройден, имеет смысл показывать поле с вопросом принудительно, вне зависимости от JS — js иногда ломается (здравствуйте, пользователи IE и хитрых антивирусов).

Илья Зверев 2009

В моём гэстбуке спамеры исчезли после ограничения количества ссылок на сообщение, например.

Денис Комарицких 2009

А как же быть с автозаполнением форм браузером при использовании скрытых полей? К примеру, в Опере (по крайней мере, чем пользуюсь, о том и знаю) мои персональные данные, включая адрес электронной почты, вставляются автоматически. Если точно так же адрес вставится и в скрытое поле (я ведь этого всё так же не замечу), то я стану роботом? Или всё же такой проблемы не существует?

Дмитрий 2009

Илья, а ты не думал об альтернативных вариантах капчи? Более божеских чем все нынешние.
Например три картинки разных фруктов. И вопрос: «На какой из картинок изображено яблоко?». Жмешь на нужную картинку, вокруг неё появляется рамка и дальше на кнопку. Прийдется только вариантов много сделать, но может это стоит того?

Илья Бирман 2009

Человеку в жизни приходится доказывать, что у него есть право на льготный проезд, что он действительно прописан по такому-то адресу, что он оплатил штраф ГАИ — это всё вещи, которые действительно требуют доказательства. Но любой человек — человек. Идея того, что это надо доказывать настолько — да — античеловечна, что независимо от способа доказательства это сразу провал.

Дмитрий 2009

Мысль понял. В принципе согласен — надо искать способ без доказательств.

Арсений Лагутов 2009

Не осилил все комментарии, но где-то читал хороший способ — одно из полей (например, Текст) неактивно до тех пор, пока юзер на него не кликнет.

Мои книги