Всё о web

Для чайников и не только


Антиспам защита форума на fluxbb

Июнь 21, 2015

Изкоробки fluxbb форум никак не защищён от автоматической регистрации. Рано или поздно наступает момент, когда владелец форума сталкивается с наплывом ботов. Они автоматически регистрируются, создают темы, сообщения и форум превращается в помойку.

Мы постараемся организовать многоступенчатую защиту ат автоматической регистрации на форуме fluxbb 1.5.8 версии.

Начнём с самого первого шага- это момент принятия пользовательского соглашения. На этом шаге разместим 2 скрытых инпута. Первый - перед формой, в него будем автоматически генерировать случайное значение. Второй инпут разместим внутри формы. В него средствами javascript будем передавать значение из первого инпута, преобразованного хэш-функцией.

Приступим. Открываем файл register.php.

Для начала нам потребуется поддержка сессий, т.к. id сессии передаётся через куки, бот должен будет уметь работать с куками. В самом начале файла, сразу после:

<?php

инициируем сессию:

session_start();

Находим место генерации формы принятия пользовательского соглашения, это примерно 500 строчка:

<div id="rules" class="blockform">
        <div class="hd"><h2><span><?php echo $lang_register['Forum rules'] ?></span></h2></div>
        <div class="box">
                <form method="get" action="register.php">
                        <div class="inform">
                                <fieldset>
                                        <legend><?php echo $lang_register['Rules legend'] ?></legend>
                                        <div class="infldset">
                                                <div class="usercontent"><?php echo $pun_config['o_rules$
                                        </div>
                                </fieldset>
                        </div>
                        <p class="buttons"><input type="submit" name="agree" value="<?php echo $lang_reg$
                </form>
        </div>
</div>

Меняем этот кусок кода на следующий:

<?php
//--- antispam 
$akey=md5(rand(-9999999,9999999));
$_SESSION['akey']=$akey;
//--- antispam 
?>
<script>
function submitagree()
{
var akey=document.getElementById("akey").value;
var mkey=0;

for(i=0; i<akey.length; i++)
  mkey+=akey.charCodeAt(i);

document.getElementById("mkey").value=mkey;
document.getElementById("agreeform").submit();
}
</script>
<input type="hidden" name="akey" id="akey" value="<?php echo $akey; ?>">
		<form method="get" action="register.php" id="agreeform">
		<input type="hidden" name="agree" value="" id="mkey">
			<div class="inform" >
				<fieldset>
					<legend><?php echo $lang_register['Rules legend'] ?></legend>
					<div class="infldset">
						<div class="usercontent"><?php echo $pun_config['o_rules_message'] ?></div>
					</div>
				</fieldset>
			</div>
			<p class="buttons"><input onclick="submitagree();" type="button" name="agree" value="<?php echo $lang_register['Agree'] ?>" /> <input type="submit" name="cancel" value="<?php echo $lang_register['Cancel'] ?>" /></p>
		</form>
	</div>
</div>

Здесь мы добавили 2 наших инпута.

<input type="hidden" name="akey" id="akey" value="<?php echo $akey; ?>">

Содержит автоматически сгенерированное значение и сохранённое в сессии. Submit заменён на обычную кнопку, на которую повешено событие onclick, по клику на которую вычисляется простейший хэш, и подставляется в инпут:

<input type="hidden" name="agree" value="" id="mkey">

Затем форма сабмитится. Почему используется такая простая хэш-функция? Потому что javascript код передаётся в открытом виде и какую бы сложную функцию Вы не использовали, злоумышленник всегда может её скопировать. Зачем же тогда эти пляски с js и хэшем? А затем, что очень немногие боты имеют поддержку javascript и даже такая простейшая операция отсечёт 99% всех спамеров.

Теперь нам нужно принять нашу форму. В районе 23 строчки находим следующий код:

if ($pun_config['o_regs_allow'] == '0')
	message($lang_register['No new regs']);


После него вставляем:

//--antispam
function myhash($val)
  {
  $res=0;
  for($i=0;$i<strlen($val);$i++)
    $res+=ord($val{$i});
  return $res;
  }
 
if(isset($_GET['agree']))
{
$mkey=$_GET['agree'];
if(isset($_SESSION['akey']))$akey=$_SESSION['akey'];
  else
    $akey=-1;
    
$reskey=myhash($akey);

if($reskey!=$mkey)$_GET['cancel']=1;

}
//--antispam

Здесь мы получили хэш со страницы принятия пользовательского соглашения и сравнили с тем, что хранится у нас в сессии. Если они не совпадают или в сессии ничего нет, тогда считаем, что пользователь не принял соглашение.

Приступаем к странице регистрации. Примерно в районе 355 строки находим:

<form id="register" method="post" action="register.php?action=register" onsubmit="this.register.disabled=true;if(process_form(this)){return true;}else{this.register.disabled=false;return false;}">

Сразу после этого вставляем:

<?php
//-- antispam
if(isset($_GET['agree']))$mkey=$_GET['agree'];
    else
      $mkey=0;
?>
<input type="hidden" name="mkey" value="<?php echo $mkey; ?>">
<?php 
//-- antispam
?>

В случае если пользователь пришел со страницы соглашения, у него в гет запросе висит хэш, подставляем его в скрытый инпут. Если же его нет, подставляем 0. Таким образом, не посетив прошлую страницу, нельзя получить верный хэш.

Далее, в районе 112 строки находим:

	if ($db->num_rows($result))
		message($lang_register['Registration flood']);

После этого вставляем :

//-- antispam
if(isset($_POST['mkey']))$mkey=$_POST['mkey'];
  else 
    $mkey='-1';

if(isset($_SESSION['akey']))$akey=$_SESSION['akey'];
  else
    $akey='-1';

$reskey=myhash($akey);

if($reskey!=$mkey)message($lang_register['Registration flood']);	    

//-- antispam

Здесь опять сравниваем то, что прислал пользователь с тем, что хранится в сессии. Если хэши не совпадают - редиректим на страницу с ошибкой. Если же совпадают - значит всё в порядке, продолжаем регистрацию.

На этом закончим, готовый файл можно скачать по ссылке. Не забывайте, что этот файл работает с fluxbb версии 1.5.8, с остальными версиями работоспособность не гарантируется.



Комментарии

4 комментариев | “Антиспам защита форума на fluxbb

  1. Аватар misha:

    Приветствую

    Просто отличное решение!
    Сделал на 1.5.9 — тоже работает.

    А вы не могли бы сделать такое для PunBB 1.4.4 ?
    На одном сайте стоит fluxbb — всё норм (БД — SQLite)

    А вот на втором хостинге только SQLite3 поддерживается.
    FluxBB работает только с SQLite2. Печаль)

    Из легких движков форумов с поддержкой sqlite3 нашел только PunBB.
    Да вот только задрали боты регистраций пользователей.

    Я хотел «в наглую» проделать то же самое (что делается здесь) с PunBB — да не нашел нужных кусков кода).

    Поможите с PunBB!

  2. Илья Илья:

    Привет. Постараюсь помочь, но к сожалению, оперативность гарантировать не могу.

  3. Аватар Саша:

    Подскажите плиз, вот сделал как у вас, но проблема в том, что теперь не возможно зарегистрировать нового пользователя с разных устройств пробывал, и ждал по несколько дней. ошибка———— (((((В течении последнего часа с вашего IP адреса уже была регистрация нового пользователя. Чтобы предотвратить мусорные регистрации, должно пройти не менее одного часа. Извините за неудобства.)))))) версия 1.5.9.

    1. Илья Илья:

      Привет. На сколько помню свою поделку, она не ограничивает регистрацию по ip адресу. Это ограничение в 1 час 100% зарыто где-то в глубине админки самого fluxbb.

Оставить комментарий:

Ваш e-mail не будет опубликован. Обязательные поля помечены *