суббота, 21 февраля 2015 г.

Битрикс: Защита от регистрации смамботов.

В сегодняшнем посте мы рассмотрим как защитить CMS Битрикс от регистрации различных спамботов. Наверняка многие сталкивались с тем, что даже при введении хорошей captcha, контрольного вопроса и др. мер в списке пользователей все же появляются "левые пользователи". Вроде (имя, фамилия): Hubertmymn HubertMrJV, JosephOl JosephOlPY и т.п. При введении подтверждения регистрации по email часть из этих пользователей оказывается с подтвержденной регистрацией, часть - нет. Не суть важно. В этой статье мы рассмотрим способ с помощью которого можно практически на 90% предотвратить подобные регистрации. Для этого мы просто подключим проверку регистрационных данных на http://www.stopforumspam.com/ , т.е. еще до регистрации пользователя мы будем проверять введенные им данные, IP и email по базе Stop Forum Spam. И если пользователь уже занесен в базу спамеров - будем отказывать в регистрации.

Основной для написания этого поста послужила статья Битрикс: защита форм от спамеров. Подключаем stopforumspam, которую я и позволю себе здесь процитировать:

Начали одолевать спамеры в комментариях, надоело каждый раз вычищать мусор после них? Предлагаю простое и эффективное решение - проверка через сервис stopforumspam.com. Stopforumspam представляет собой базу данных ip адресов, емайлов и логинов, под которыми регистрируются боты спамеров. Доступ свободный для получения информации, чтобы добавить злостного спамера в базу надо зарегистрироваться. Для многих движков сайтов и форумов есть готовые плагины. Запрос информации — это обычный get запрос, все очень просто и понятно.

Подключаем проверку в "Битрикс: управление сайтом". К примеру, это может выглядеть следующим образом. В /bitrix/components/ создаем папку tools, куда ложим файл tools.php:

<?php
function checkSpambots($mail='', $ip='', $name='') {
$spambot = false;
$dir = $_SERVER["DOCUMENT_ROOT"].'/spambot/';
if($mail!=''){
$xml_string = file_get_contents('http://www.stopforumspam.com/api?email=' . $mail);
$xml = new SimpleXMLElement($xml_string);
if ($xml->appears == 'yes') {
$spambot = true;
}
}
if($ip!='' and $spambot===false) {
//e-mail not found in the database, now check the ip
$xml_string = file_get_contents('http://www.stopforumspam.com/api?ip=' . $ip);
$xml = new SimpleXMLElement($xml_string);
if ($xml->appears == 'yes') {
$spambot = true;
}
}
if($name!='' and $spambot===false) {
$xml_string = file_get_contents('http://www.stopforumspam.com/api?username=' . $name);
$xml = new SimpleXMLElement($xml_string);
if ($xml->appears == 'yes') {
$spambot = true;
}
}
if ($spambot == true) {
if (file_exists($dir . $ip . '.txt')) {
$spambot_old_info = file_get_contents($dir . $ip . '.txt');
$spambot_old_info = explode(',', $spambot_old_info);
$spambot_old_info[2] = $spambot_old_info[2] + 1;
$spambot_old_info = implode(',', $spambot_old_info);
file_put_contents($dir . $ip . '.txt', $spambot_old_info);
} else {
$spambot_info = $ip . ',' . $name . ',1';
file_put_contents($dir . $ip . '.txt', $spambot_info);
}
}
return $spambot;
}
if(strip_tags($_POST["NAME"]) != "") $arResult["NAME"] = trim(strip_tags($_POST["NAME"]));
else $arResult["ERROR"][] = GetMessage("COMMENT_ERROR_NAME");
if($_POST["WWW"] != "") $arResult["WWW"] = trim(strip_tags($_POST["WWW"]));
if ($_SERVER["HTTP_X_FORWARDED_FOR"]) $clientIP = $_SERVER["HTTP_X_FORWARDED_FOR"];
else $clientIP = $_SERVER["HTTP_CLIENT_IP"];
$clientProxy = $_SERVER["REMOTE_ADDR"];
if(strlen($clientIP) <= 0) {
$clientIP = $clientProxy;
$clientProxy = "";
}
if(checkSpambots('',$clientIP,'')===true) $arResult["ERROR"][] = "Изыди, проклятый спамер!"
require_once ($_SERVER["DOCUMENT_ROOT"].'/bitrix/components/tools/tools.php');
AddEventHandler("main", "OnBeforeUserRegister", Array("XUser", "BeforeRegister"));
class XUser {
function BeforeRegister(&$arFields) {
$spambot = checkSpambots($arFields['EMAIL'], $arFields['USER_IP'], $arFields['NAME']);
if ($spambot == true) {
$GLOBALS['APPLICATION']->ThrowException('Registration is forbidden for you. Send abuse to the administrator<br>Вам регистрация запрещена. Обратитесь к администратору');
return false;
}
}
}

Функция принимает параметрами емайл, айпи-адрес и логин субъекта, пытающегося оставить комментарий, и последовательно проверяет их путем запроса к stopforumspam.com. Если хоть по одному параметру пользователь уличен в спамерстве, создаем (или обновляем если уже есть) файлик с данными о спамере и количеством попыток - это будет примитивный журнал вторжений :)

Вызов функции может выглядеть так (где-то в компоненте):

if(strip_tags($_POST["NAME"]) != "") $arResult["NAME"] = trim(strip_tags($_POST["NAME"]));
else $arResult["ERROR"][] = GetMessage("COMMENT_ERROR_NAME");

if($_POST["WWW"] != "") $arResult["WWW"] = trim(strip_tags($_POST["WWW"]));

if ($_SERVER["HTTP_X_FORWARDED_FOR"]) $clientIP = $_SERVER["HTTP_X_FORWARDED_FOR"];
else $clientIP = $_SERVER["HTTP_CLIENT_IP"];

$clientProxy = $_SERVER["REMOTE_ADDR"];
if(strlen($clientIP) <= 0) {
 $clientIP = $clientProxy;
 $clientProxy = "";
}
if(checkSpambots('',$clientIP,'')===true) $arResult["ERROR"][] = "Изыди, проклятый спамер!"

Чтобы функцию можно было вызывать беспроблемно в любом месте кода, в файл /bitrix/php_interface/init.php добавляем строчку

require_once ($_SERVER["DOCUMENT_ROOT"].'/bitrix/components/tools/tools.php');

Это был пример для комментариев. Если на сайте разрешено комментировать только зарегистрированным пользователям, особо упорные спамеры могут даже зарегистрироваться, чтобы нагадить в блоге или форуме. Чтобы защитить сайт от спамеров сразу в процессе регистрации и пресечь ее на корню, в том же файле /bitrix/php_interface/init.php добавляем код:

AddEventHandler("main", "OnBeforeUserRegister", Array("XUser", "BeforeRegister"));

class XUser {
 function BeforeRegister(&$arFields) {
  $spambot = checkSpambots($arFields['EMAIL'], $arFields['USER_IP'], $arFields['NAME']);
  if ($spambot == true) {
   $GLOBALS['APPLICATION']->ThrowException('Registration is forbidden for you. Send abuse to the administrator<br>Вам регистрация запрещена. Обратитесь к администратору');
    return false;
  }
 }
}

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

p.s. Можно просто скопировать данный пример и произвести все операции описанные в статье, однако, я бы, например, не стал вести "журнал вторжений" в текстовом файле. В Битрикс есть встроенный журнал событий и можно добавлять записи непосредственно в него, если это необходимо. Возможно чуть позже я опишу способ как это сделать.

2 комментария :

  1. Код вызывает критическую ошибку и сайт не грузится, require_once ($_SERVER["DOCUMENT_ROOT"].'/bitrix/components/tools/tools.php'); - error line 9

    ОтветитьУдалить
    Ответы
    1. А вы уверены что файл tools.php у вас действительно есть по /bitrix/components/tools/ ? Запакуйте свои /bitrix/php_interface/init.php и /bitrix/components/tools/tools.php и покажите. Посмотрим.

      Удалить