Повадился на мой форум лазить хрумер, проклятие на оба дома придумавших эту бесовскую программу. Но как говорится, и со старухой бывает порнуха, ой, на старуху найдется проруха. У меня уже 2 недели отключена капча и ни одной левой регистрации и сообщения. Обычно было около 10 новых роботов в день.
Похожу идею борьбы с автоматическим спамом я описывал и предлагал обсудить еще раньше. Но саму идею я немного переработал. Итак сама идея:
1) Пользователь заходит на форум — создается ассоциативный массив в котором ключи это названия полей, которые идут в оригинале, а значение новое имя поля. Массив записывается в сессию.
2) Средствами javascript изменяем названия полей.
3) Добавляем проверку в получение данных: мы должны проверять, если в массиве созданном в пункте один есть ключ совпадающий с именем запрашиваемого поля, то значение берется из переменной $_POST имя которой совпадает с найденным значением.
Теперь сама реализация.
1) Открываем файл common.php. После строки
$starttime = $starttime[1] + $starttime[0];
Добавляем следующее:
ini_set('session.use_only_cookies', '1'); ini_set('session.auto_start', '1'); session_start(); /** * @author Aravak * @site https://js-php.ru/ * */ function anti_spam_aravak() { global $aAntiSpamVarNames; if( !array_key_exists('generated_names' , $_SESSION) ) { $aAntiSpamVarNames = array("username" => uniqid('us'), "new_password" => uniqid('pwd'), "email" => uniqid('eml'), "email_confirm" => uniqid('eml2'), "message" => uniqid('msg') ); $_SESSION['generated_names'] = $aAntiSpamVarNames; } else { $aAntiSpamVarNames = $_SESSION['generated_names']; } } anti_spam_aravak();
Немного поясню: в функцию uniqid, как значение можете передавать какую угодно строку, или совсем ничего не передавать. Но на мой взгляд лучше придумать что-то свое, уникальное. Итак, нужный нам массив мы создали.
2. Открываем includes/functions.php и в конец добавляем такую вот функцию:
function getAntiSpanJavaScript() { global $aAntiSpamVarNames; $script = ''; $jsArrayUniqName = uniqid('cvr'); $script = " var RewritedMessageName; function myRewrite() { var ".$jsArrayUniqName." = new Array();"; foreach( $aAntiSpamVarNames as $realName => $securName ) { $script .= $jsArrayUniqName . "['".$realName."'] = '".$securName ."';"; } $script .= " var allInputs = document.getElementsByTagName('input'); var allTextareas = document.getElementsByTagName('textarea'); var allElems = new Array(); for(var i=0; i< allInputs.length; i++) { if( (allInputs[i].type==\"text\" || allInputs[i].type==\"password\") && allInputs[i].name ) { allElems[allElems.length] = allInputs[i]; } } for(var i=0; i< allTextareas.length; i++) { if( allInputs[i].name ){ allElems[allElems.length] = allTextareas[i]; } } for(var i=0; i< allElems.length; i++) { if( allElems[i].name ){ var inputName = allElems[i].name; if(".$jsArrayUniqName."[inputName]){ allElems[i].name = ".$jsArrayUniqName."[inputName]; } } } RewritedMessageName = " . $jsArrayUniqName . "['message'] }"; return $script; }
Объясню, почему это добавляется в php-коде. Во-первых php быстрее чем шаблонизатор, во-вторых, по секрету скажу, есть еще функция шифрования javascript, правда из-за сырости я её пока не выкладываю, появится позже, в платной версии.
3. В этом же файле, после строки
'T_STYLESHEET_NAME' => $user->theme['theme_name'],
добавьте строку
'SITE_ANTI_SPAM_JS' => getAntiSpanJavaScript(),
4. Тут же находим функцию request_var и сразу после открывающейся скобки пишем следующее:
global $aAntiSpamVarNames; if( isset($aAntiSpamVarNames[$var_name]) ){ $var_name = $aAntiSpamVarNames[$var_name]; }
5. Переходим к шаблону. Открываем файл вашей темы под названием overall_header.hml и после строки
<script type="text/javascript"> // <![CDATA[
добавляем
{SITE_ANTI_SPAM_JS}
5. Теперь идем в файл overall_footer и переде тэгом </body> пишем следующее:
<script type="text/javascript"> myRewrite(); </script>
6. Теперь еще небольшая работа — делаем, чтобы bb-коды работали корректно с новыми именами полей. Открываем в папке с темой файл editor.js и первыми сроками пишем такую функцию:
function getTextarea() { var doc; if (document.forms[form_name]) { doc = document; return doc.forms[form_name].elements[RewritedMessageName]; } else { return opener.document.getElementsByTagName('textarea')[0]; } }
Далее по коду, все конструкции типа
var textarea = doc.forms[form_name].elements[text_name];
заменяем на
var textarea = getTextarea();
Все. чистим кэш, проверяем работу. Приведенный тут пример корректно работает с темой aeroblue и вроде как subsilver. На других темах не проверял, но уверен, что проблем не будет.
Теперь плюсы данного способа:
1) Никакого неудобства пользователям, типа супер-сложной капчи или дополнительных полей.
2) Ни одного спам-комментария за 2 недели.
3) Легкая интеграция.
4) Защита как от автоматических регистраций так и от отправки сообщения.
Минусы:
1) Хрумер быстро научится обходить данную защиту как только она станет массовой, но он еще долго не сможет выполнить зашиврованный javascript о котором я писал выше.
2) Новые значения полей легко спарсить, но опять же пункт 1, фраза после запятой.
3) Не работает у тех, у кого отключен js, но это как мне кажется их проблема — с отключенным js читайте на здоровье, но писать, уж увольте.
Буду благодарен за ссылочку на мой блог с форума, который воспользуется данной технологией. Также планирую быстро сваять плагин для WP ибо, работающий сейчас у меня, который создает чекбокс с дополнительным именем пробивается роботами, не сильно часто, но факт есть. Как вариант защиты, можно еще заказывать создание сайтов у профессионалов.
Хрумак как и весь черный СЕО явление пренеприятнейшее, но, увы, реальное. Мы им капчу, а они нам свои пути обхода.
Ну с данным решением пока проблем не было, а ставить очень сложную капчу э то лишнее неудобство пользователю
Согласен, сильно сложная капча — зло. Обидно бывает накатать здоровый комментарий, а потом ошибиться при вводе капчи, да еще если текст не сохраняется.
Здравствуйте!
Есть небольшая корпоративная сеть, почта крутится на собственном почтовом сервере. Посоветуйте, плз, какое-нибудь решение для защиты от спама — в теме разбираюсь слабо, а делать надо 🙂
Тут я думаю немного не про то речь, вам скорее нужны фильтры, чем вот такие вот формочки 🙂