Wordpress

индекс
133,78

Bender против Спама

Вы ведете standalone-блог? На Wordpress? Атакуют китайские боевые роботы спамеры?

В последнее время разговоры в блогах все крутятся вокруг порядком надоевшего спама. От этой заразы не помогают ни <noindex>, ни санкции Яндекс по отношению к сплогам (их сейчас модно называть тематическими блогами, но на самом деле это те же сателлиты с переведенным/отсканированным/измененным контентом). Даже то, что ссылки с блогов стали играть меньшую роль в ранжировании, не останавливает тех школьников, пытающихся «заработать» на разнообразных Блогунах, ДжейТуДжеях и ПрофитБлогах (ну или «нерезидентов» с Сапы, да). И убирать поле URL — не хочется, все-таки это одновременно и мотивация комментаторов, и возможность обратной связи с ними.

Если говорить о ручном спаме, от которого не спасут никакие меры предосторожности (а вы представьте себе, кто-то умудряется на нем зарабатывать и не 0.01 цент), то до какого-то времени было два основных способа защиты. Премодерация, которая заставляет постоянно проверять стек на проверку (пока диалоги в блоге замирали), и Акисмет, порой отправляющий в спам и нормальных комментаторов (иногда — надолго). Теперь нам предложили альтернативу Parasite Eliminator, которая тоже имеет недостатки, но позволяет справиться с засильем вручную написанных «спасибо» и «отлично» со ссылками на ужасные сайты и ужасные же сплоги.

От автоматического спама защищаются в основном капчей (Акисмет тоже нацелен на это — но опять же, разбирать завалы «спасибок» — нерадостная перспектива). Это плохое решение для небольшого блога — и не потому, что даже не очень простую капчу можно взломать, и ее действительно взламывают, когда она становится популярной. В первую очередь, капча заставляет посетителя, который хочет просто оставить комментарий, вглядываться в картинку или складывать цифры, а потом еще делать лишнее телодвижение, переписывая их в поле ввода. Т.е., пользуясь терминологией Смирнова, это фашизм. Ммм, все помнят кошечек и собачек на Рапиде?

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



Шаг 1


Этот шаг абсолютно совместим с обновлениями Wordpress.

Для начала создаем в корневом каталоге сайта файл с названием вида send-comment.php (называем его как хотим). В нем всего одна строчка:

<?php include_once('wp-comments-post.php'); ?>

В .htaccess добавляем строчки, запрещающие обращаться к оригинальному скрипту отправки комментария:

<Files wp-comments-post.php>
order allow,deny
deny from all
</Files>


После этого изменяем форму комментариев в шаблоне темы (файл comments.php), чтобы действие вело на новый скрипт:

<form action="http://ваш-сайт.ru/send-comment.php" method="post" id="commentform">

Шаг 2


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

Т.к. некоторые спамилки могут выуживать скрипт и имена полей из формы, то нам надо всего лишь изменить название поля. Понятно, что поля name-email-url должны остаться стандартными, чтобы комментатору легко было заполнять их автоподстановкой браузера. Поэтому изменять будем название поля textarea в comment.php шаблона темы.

И не просто изменим, а добавим новое, которое станет «настоящим»:

<textarea name="comment" id="comment" class="commentarea" cols="40" rows="10"></textarea>
<textarea name="comment-tekst" id="comment-text" cols="40" rows="10" class="text"></textarea>


Опять же, поле comment-text называем по своему усмотрению. В style.css же скрываем старое поле:

.commentarea{
width: 0;
height: 0;
border: 0;
}


Можно скрыть его так, можно сдвинув его по position:absolute, или, как предлагает автор, заключить textarea в div и сдвигать именно его. Все зависит от вашей фантазии.

После чего, изменяем wp-comments-post.php, добавляя туда название нашего нового поля и делая проверку на старое:

$spam_test_field = trim($_POST['comment']);
if(!empty($spam_test_field)) wp_die('Спаму нет!');

$comment_author = trim(strip_tags($_POST['author']));
$comment_author_email = trim($_POST['email']);
$comment_author_url = trim($_POST['url']);
$comment_content = trim($_POST['comment-tekst']);


После чего все эти хрумеры, пытающиеся пробиться к вашему файлу (либо если вы не выполнили шаг 1, либо если они все-таки нашли скрипт отправки комментария), будут умирать и корчиться.

Шаг 3


Конечно, оба эти способа можно вычислить, ровно как и капчу, — названия полей легко читаются в HTML страницы. Однако, пока этот способ защиты от автоматического спама в Wordpess работает и никак не мешает вашим комментаторам общаться с вами и между собой, все нормально.

В сочетании с Parasite Eliminator — вы, наверное, и совсем забудете, что такое спам (острая консервированная ветчина?).

Теперь вы во всеоружии. Приятного ведения блога без спама!
+20
11 ноября 2008, 16:00
32

комментарии (52)

+1
Kela #
Я себе поставил wp-spamfree и забыл, что такое спам!
+2
Tod #
Аналогично — по моему самый эффективный плагин против спама и ничего придумывать не нужно.
Добавить к нему Акисмет, предварительную модерацию первого комментариях любого пользователя — и все, ка в танке:)
Из 2тыс. спам сообщений за пару дней теперь меньше 10-ти за неделю!
0
Kela #
Именно так, как вы написали я и сделал… Весь комплекс вместе решил проблему на 101%!
WP-SpamFree has blocked 1,273 spam comments.
Блог не особопосещаемый, но результат на лицо!
+1
marapper #
Обязательность кукисов и включенного js — тоже в некотором роде фашизм. Ставить ограничение на комментирование параноиками типа меня (NoScript под FF) мне не кажется 100-процентным решением.
+1
Tod #
Автор плагина так и говорит 98-99% :)
Согласен, что решение не супер классное, но выгребать по 500 комментариев спама и 10-15 «умного» нет сил) Если несколько блогов, то затраченное время еще больше.
+1
Novikov #
А мне пользователи спамфри присылают регулярно пачки спама. Автоматического.
0
kryzander #
а я поставил Spam Karma 2. с тем же результатом :) правда, приходится сначала опытным путем подобрать нужные настройки, чтобы нормальные люди в спам не улетали. Но в целом — ложных срабатываний минимум, и то на действительно спорных случаях (добил в свое время спам без ссылок. Просто спамовый текст, но ни одной ссылки нигде :)) собственно, он немного и подпортил автоматику))
+1
iv1 #
image
0
t0os #
спасибо за ссылку, только что поставил. заколебался разгребать спам с админки.
+3
ruskar #
А я малость усложнил всё. В корневой папке создал файлик antispam.php с следующим содержанием:

function getFieldName() {
	$salt = 'ds';
	return $fieldname = $salt.md5(date('d.m.Y'));
}


В файле wp-comments-post.php заменил:
$comment_content = trim($_POST['comment-tekst']);
на
$comment_content = trim($_POST[getFieldName()]);


В файле comments.php заменил:
<textarea name="comment-tekst" id="comment-text" cols="40" rows="10" class="text"></textarea>

на
<textarea name="<?php echo getFieldName(); ?>" id="<?php echo getFieldName(); ?>" cols="40" rows="10" class="text"></textarea>


Ну и соответственно подключил файл antispam.php в обозначенных выше файлах.
+1
marapper #
Отлично! Не повезет, конечно, полуночникам %)
+3
ruskar #
Есть ещё вариант для параноиков, со сменой алгоритма шифрования и пересаливанием каждые два часа:

function getFieldName() {
	$salt = '';
	$hash = '';
	switch(date('H')) {
		case 3:
		case 4:
		case 7:
		case 8:
		case 17:
		case 18:
		case 11:
		case 12:
			$salt = 'xs'.date('H');
			$hash = hash('haval128,5', date('d.m.Y'));
			break;
		case 1:
		case 2:
		case 13:
		case 14:
			$salt = 'we'.date('H');
			$hash = hash('haval256,5', date('d.m.Y'));
			break;
		case 15:
		case 16:
		case 19:
		case 20:
			$salt = 'aq'.date('H');
			$hash = hash('haval160,5', date('d.m.Y'));
			break;
		case 23:
		case 24:
		case 0:
		case 5:
		case 6:
			$salt = 'ki'.date('H');
			$hash = hash('sha1', date('d.m.Y'));
			break;
		case 9:
		case 10:
		case 21:
		case 22:
			$salt = 'bg'.date('H');
			$hash = md5(date('d.m.Y'));
			break;
		default:
			$salt = 'xc'.date('H');
			$hash = md5(date('d.m.Y'));
	}
	return $salt.$hash.date('H');
}

0
kurokikaze #
Вот это дело, спасибо :) А на стыке пересаливания коммент запостить не получится, стало быть? )
+1
ruskar #
Ну да, единственный недостаток, если допустим пользователь открыл страницу с постом в 22:59, две минуты писал коммент и отправил его уже в 23:01, то по идее у него не добавиться пост. Но это поправимо, сейчас допишу эту функцию так, чтобы на «стыках», в течение пяти минут (с 23:00 до 23:05 например) удовлетворяло условию как новое имя поля, так и старое.
+3
ruskar #
Исправленная функция:

function getFieldName($hour = 25) {
	$salt = '';
	$hash = '';
	if($hour == 25) $hour = date('H');
	switch($hour) {
		case 3:
		case 4:
		case 7:
		case 8:
		case 17:
		case 18:
		case 11:
		case 12:
			$salt = 'xs'.date('H');
			$hash = hash('haval128,5', date('d.m.Y'));
			break;
		case 1:
		case 2:
		case 13:
		case 14:
			$salt = 'we'.date('H');
			$hash = hash('haval256,5', date('d.m.Y'));
			break;
		case 15:
		case 16:
		case 19:
		case 20:
			$salt = 'aq'.date('H');
			$hash = hash('haval160,5', date('d.m.Y'));
			break;
		case 23:
		case 24:
		case 0:
		case 5:
		case 6:
			$salt = 'ki'.date('H');
			$hash = hash('sha1', date('d.m.Y'));
			break;
		case 9:
		case 10:
		case 21:
		case 22:
			$salt = 'bg'.date('H');
			$hash = md5(date('d.m.Y'));
			break;
		default:
			$salt = 'xc'.date('H');
			$hash = md5(date('d.m.Y'));
	}
	return $salt.$hash.date('H');
}


В файле wp-comments-post.php также меняем
$comment_content = trim($_POST[getFieldName()]);

на
$comment_content = trim($_POST[getFieldName()]);
if(empty($comment_content) && (date('h') % 2) == 1)
$comment_content = trim($_POST[getFieldName(intval(date('H')) - 1)]);


В итоге во время нечётных часов валидны два имени поля — для текущего часа и для предыдущего. Во время чётного часа валидно только имя поля для текущего часа. Имя поля и соль меняются после окончания чётного часа.
+1
marapper #
Клевое решение, немного избыточное, правда — если спамилка будет парсить форму, то никакие ухищрения не помогут.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
0
marapper #
Внимательней читайте. Через каждые два часа меняется алгоритм, но первый час еще действует И предыдущий. То есть время действия в общем каждого — 3 часа внахлест.

Если комментатор пришел без одной минуты до пересалки, то у него — целый час, чтобы оставить «спасибо, очень понравилось». Если позже — то он попадает на новый алгоритм.

В случае же, если кто-то оставил страницу надолго, то при правильном подходе к созданию формы, возврат назад не сотрет инфу в области коммента, и его можно будет отправить еще раз.
0
Uclaxyr #
Да, народ уже привык, что открытая вчера страница может не отправить пост (камент, правку и т. п.) из-за потери сессии или других проблем. Я, например, старые страницы часто перед написанием обновляю. Ну и нажать „назад“ действительно тоже наглядно.

Спасибо за интересное решение!
0
Uclaxyr #
В новой версии Вордпресса в wp-comments-post.php будет так?

$comment_author = ( isset($_POST['author']) )? trim(strip_tags($_POST['author'])): null;
$comment_author_email = ( isset($_POST['email']) )? trim($_POST['email']): null;
$comment_author_url = ( isset($_POST['url']) )? trim($_POST['url']): null;
$comment_content = ( isset($_POST[getFieldName()]) )? trim($_POST[getFieldName()]): null;
if(empty($comment_content) && (date('h') % 2) == 1)
$comment_content = trim($_POST[getFieldName(intval(date('H')) — 1)]);
+1
marapper #
ну что-то вроде. Но теперь можно и без хака этого файла обойтись — я плагин попозже напишу.
0
Uclaxyr #
Вы правда здесь в каментах объя́вите об этом?
Было бы здорово; хотя без плагина коленными правками уже заработало. Но так будет неудобно обновлять WP; постоянно помнить, в какой файл что ещё приписать.
+3
ruskar #
Свежие новости с фронта от меня:

Представители спамеров уже регистрируются в социальных сетях и присылают угрозы физической расправы членам красного списка :) По крайней мере мне прислали :) Найти меня в контакте было легко — адрес на профайл висит в блоге.
+3
ruskar #
Фак, извиняюсь, не в той теме оставил комментарий…
0
marapper #
Я немного подожду и тоже закинусь в красный список :)
НЛО прилетело и опубликовало эту надпись здесь
0
Recluse #
Это уже придется сделать «ручками» для каждого конкретного блога, что в разы увеличивает трудоемкость + отсеивает чисто автоматический спам. :)
НЛО прилетело и опубликовало эту надпись здесь
0
Recluse #
Для этого, как минимум, придется изменять существующие системы рассылок, а это уже немало :)
НЛО прилетело и опубликовало эту надпись здесь
0
Recluse #
Я разве их предлагал? :)
0
marapper #
Да легко на самом деле сканировать страницу — выдираем все поля формы, экшн — и вуаля, можем, спамить. Но, пока «умных» ботов мало — работает просто переименование. Для чуть более умных и заточенных под ВП — мы оставляем старое поле, но делаем его ненужным.

Когда придумают, как это быстро и легко обходить (и сделают) — тогда мы придумаем, как обходить их.
0
ruskar #
Если в логику бота внесут что-то вроде «использовать имя поля комментария, не равное comment», то можно сделать три поля комментария с именами comment, первое зашифрованное и второе зашифрованное, второе зашифрованное использовать как ловушку. В таком случае уже и сканирование страницы не поможет — бот должен догадаться какое из полей использовать.
+1
marapper #
А чтобы все не использовал, при повторной попытке после fail, запрещать работу скрипта. В общем, можно довести скрипт до состояния хорошо защищенной крепости — с волчьими ямами, кипящей смолой и сотней арбалетчиков в бойницах )

Но все равно спамеры умрут лишь с изменениями в поисковых системах. Скажем, если перестать передавать вес с ссылок с микроформатом rel=«commentauthor», уйдет SEO. Со SMO и привлечением траффика же бороться другими способами.
0
mytribune #
Понятно откуда: Лично про Вас никто ничего и не выясняет. Спамеры просто парсят выдачу поисковиков по запросам типа «Leave a Comment Wordpress» и другим аналогичным. И находят сотни тысяч страниц с формами. После этого проезжаются по всем этим страницам постилкой (и на большинстве блогов это срабатывает, видимо). Где-то капча, где-то премодерация, где-то другие средства — там облом. Но спамеры этого и проверять не станут, потому что из-за нескольких умных блоггеров возиться лень, а у большинства ссылка успешно отобразится.
0
ruskar #
Если бот будет сканировать HTML-код страницы и оттуда выдирать имя поля отправки комментария, то в принципе легко сможет обойти предложенную защиту. Для этого нужно делать дополнительные ловушки.
0
payalnik #
А если просто закрыть все возможности поместить УРЛы в комментарий, разве спам не исчезнет?
+6
Goodkat #
спам исчезнет, если оторвать спамерам руки
–1
nicothin #
лучше — голову.
и яйца.
+1
Goodkat #
голову — слишком жестоко.
а как отсутствие яиц может помешать спамеру спамить? о_О
0
nicothin #
ну, если их отрезать после головы, — это, в принципе, ничего не меняет, — спаммить человек уже не будет.

а голову я предлагал отрезать в состоянии аффекта…
0
Goodkat #
месть в состоянии аффекта — не наш метод.
наши методы сугубо функциональны: человек спамит руками, если оторвать ему руки, то спамить не будет.
+1
cwer #
Автоматический нет. Будут спамить по привычке :)
0
payalnik #
Ну там можно поменять какой-нибудь дефолт, чтобы робот стух
+1
marapper #
Можно и отослать всем спаммерам письмо, чтобы они перестали писать в блог — результат тоже.
0
marapper #
спамерам, идиот!
0
kai #
Забавно, можно ли сделать автоматические рандомные значения для имен полей и переменных? =) Было бы прикольно.
0
Arseny_Info #
А чем плохо вот такое решение от автоспама?
0
marapper #
Требование JavaScript, лишнее движение, чтобы нажать чекбокс (в некоторых случаях неправильной установки плагина приводит к обратным результатам), ну и лишний код. Как раз то, что в моих условиях хотелось обойти.

Зато без изменений в движке, да.

Но взламываемость в случае распространения — аналогичная описанному мною способу (у использования псевдослучайной пересалки поле выше — гораздо выше, но тоже возможно).
0
LDEV #
Динамические имена полей — в зависимости от ip и текущего часа:

function get_field($name) {
$date = date('j');
$ip = get_my_ip();
$str = SITE_SALT. $date. $ip. $name;
return md5($str);
}

для каждого поля вызываем get_field('email'), проверяем аналогично $email = $_POST[get_field('email')];

очень удобно получается, если переопределять свой $_POST, и в начале скрипта искать в исходном все поля like md5, и вставлять нормальные имена — тогда и скрипты переделывать не надо, только формы динамические.
0
mkdotam #
Offtopic: взломали lleo.aha.ru/dnevnik/ (;

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.