Off topic: Antispam mod for phpBB

Technical support, bug reports, feature requests and more.

Off topic: Antispam mod for phpBB

Postby admin on Sat Feb 10, 2007 9:02 pm

The community has asked me to share the antispam mod for this forum. When I started getting 3-4 spam topics a day in november, I added a simple question that a spambot can't answer: "What do the letters 'JS' in Highslide JS stand for?".

Since then I haven't received a single spam topic. Personally I think this is the simplest and best antispam solution available. As long as spambots don't have AI, they will never crack it. And if a living person tells them how to, I'll just change the question.

Please note that this is a quick and dirty mod that I did for my own convenience, and I take no responsibility for how it might affect your installation. phpBB guru's might see weaknesses in this approach, and if they take this mod further I would only be happy.

Here is how you IQ test your users in four steps (phpBB version 2.0.21) :


1) In includes\usercp_register.php line 274, change this:

Code: Select all
if ($board_config['enable_confirm'] && $mode == 'register')
{
   if (empty($HTTP_POST_VARS['confirm_id']))
   {
      $error = TRUE;
      $error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong'];
   }
   else
   {
      $confirm_id = htmlspecialchars($HTTP_POST_VARS['confirm_id']);
      if (!preg_match('/^[A-Za-z0-9]+$/', $confirm_id))
      {
         $confirm_id = '';
      }
      
      $sql = 'SELECT code
         FROM ' . CONFIRM_TABLE . "
         WHERE confirm_id = '$confirm_id'
            AND session_id = '" . $userdata['session_id'] . "'";
      if (!($result = $db->sql_query($sql)))
      {
         message_die(GENERAL_ERROR, 'Could not obtain confirmation code', __LINE__, __FILE__, $sql);
      }
         if ($row = $db->sql_fetchrow($result))
      {
         if ($row['code'] != $confirm_code)
         {
            $error = TRUE;
            $error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong'];
         }
         else
         {
            $sql = 'DELETE FROM ' . CONFIRM_TABLE . "
               WHERE confirm_id = '$confirm_id'
                  AND session_id = '" . $userdata['session_id'] . "'";
            if (!$db->sql_query($sql))
            {
               message_die(GENERAL_ERROR, 'Could not delete confirmation code', __LINE__, __FILE__, $sql);
            }
         }
      }
      else
      {      
         $error = TRUE;
         $error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong'];
      }
      $db->sql_freeresult($result);
   }
}


To this:

Code: Select all
if ($board_config['enable_confirm'] && $mode == 'register')
{
   if (strtolower($confirm_code) != strtolower($lang['Confirm_code_answer']))
   {
      $error = TRUE;
      $error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong'];
   }
}


2) In includes\usercp_register.php line 945, change this:

Code: Select all
$confirm_image = '';
if (!empty($board_config['enable_confirm']) && $mode == 'register')
{

   $sql = 'SELECT session_id
      FROM ' . SESSIONS_TABLE;
   if (!($result = $db->sql_query($sql)))
   {
      message_die(GENERAL_ERROR, 'Could not select session data', '', __LINE__, __FILE__, $sql);
   }

   if ($row = $db->sql_fetchrow($result))
   {
      $confirm_sql = '';
      do
      {
         $confirm_sql .= (($confirm_sql != '') ? ', ' : '') . "'" . $row['session_id'] . "'";
      }
      while ($row = $db->sql_fetchrow($result));
   
      $sql = 'DELETE FROM ' .  CONFIRM_TABLE . "
         WHERE session_id NOT IN ($confirm_sql)";
      if (!$db->sql_query($sql))
      {
         message_die(GENERAL_ERROR, 'Could not delete stale confirm data', '', __LINE__, __FILE__, $sql);
      }
   }
   $db->sql_freeresult($result);

   $sql = 'SELECT COUNT(session_id) AS attempts
      FROM ' . CONFIRM_TABLE . "
      WHERE session_id = '" . $userdata['session_id'] . "'";
   if (!($result = $db->sql_query($sql)))
   {
      message_die(GENERAL_ERROR, 'Could not obtain confirm code count', '', __LINE__, __FILE__, $sql);
   }

   if ($row = $db->sql_fetchrow($result))
   {
      if ($row['attempts'] > 3)
      {
         message_die(GENERAL_MESSAGE, $lang['Too_many_registers']);
      }
   }
   $db->sql_freeresult($result);
   
   // Generate the required confirmation code
   // NB 0 (zero) could get confused with O (the letter) so we make change it
   $code = dss_rand();
   $code = substr(str_replace('0', 'Z', strtoupper(base_convert($code, 16, 35))), 2, 6);

   $confirm_id = md5(uniqid($user_ip));

   $sql = 'INSERT INTO ' . CONFIRM_TABLE . " (confirm_id, session_id, code)
      VALUES ('$confirm_id', '". $userdata['session_id'] . "', '$code')";
   if (!$db->sql_query($sql))
   {
      message_die(GENERAL_ERROR, 'Could not insert new confirm code information', '', __LINE__, __FILE__, $sql);
   }

   unset($code);
   
   $confirm_image = '<img src="' . append_sid("profile.$phpEx?mode=confirm&amp;id=$confirm_id") . '" alt="" title="" />';
   $s_hidden_fields .= '<input type="hidden" name="confirm_id" value="' . $confirm_id . '" />';

   $template->assign_block_vars('switch_confirm', array());
}


To this:

Code: Select all
// Visual Confirmation
$confirm_image = '';
if (!empty($board_config['enable_confirm']) && $mode == 'register')
{
   $template->assign_block_vars('switch_confirm', array());
}



3) In templates\subSilver\profile_add_body.tpl line 59 change this:

Code: Select all
<!-- BEGIN switch_confirm -->
<tr>
   <td class="row1" colspan="2" align="center"><span class="gensmall">{L_CONFIRM_CODE_IMPAIRED}</span><br /><br />{CONFIRM_IMG}<br /><br /></td>
</tr>
<tr>
  <td class="row1"><span class="gen">{L_CONFIRM_CODE}: * </span><br /><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN}</span></td>
  <td class="row2"><input type="text" class="post" style="width: 200px" name="confirm_code" size="6" maxlength="6" value="" /></td>
</tr>
<!-- END switch_confirm -->


To this:

Code: Select all
<!-- BEGIN switch_confirm -->
<tr>
  <td class="row1"><span class="gen">{L_CONFIRM_CODE}: * </span><br /><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN}</span></td>
  <td class="row2"><input type="text" class="post" style="width: 200px" name="confirm_code" size="6" maxlength="10" value="" /></td>
</tr>
<!-- END switch_confirm -->


4) In language\lang_english\lang_main.php line 656 change this:

Code: Select all
//
// Visual confirmation system strings
//
$lang['Confirm_code_wrong'] = 'The confirmation code you entered was incorrect';
$lang['Too_many_registers'] = 'You have exceeded the number of registration attempts for this session. Please try again later.';
$lang['Confirm_code_impaired'] = 'If you are visually impaired or cannot otherwise read this code please contact the %sAdministrator%s for help.';
$lang['Confirm_code'] = 'Confirmation code';
$lang['Confirm_code_explain'] = 'Enter the code exactly as you see it. The code is case sensitive and zero has a diagonal line through it.';


To this:

Code: Select all
//
// Visual confirmation system strings
//

$lang['Too_many_registers'] = 'You have exceeded the number of registration attempts for this session. Please try again later.';
$lang['Confirm_code'] = 'Antispam confirmation';
$lang['Confirm_code_explain'] = 'What is the last name of the president of the US?';
$lang['Confirm_code_answer'] = 'bush';
$lang['Confirm_code_wrong'] = 'The confirmation answer you entered was incorrect. Hint: the correct answer is a four-letter word that starts with a B and rhymes with push.';
User avatar
admin
Site Admin
 
Posts: 5971
Joined: Thu Nov 09, 2006 1:22 pm
Location: Vik i Sogn, Norway

Return to Highslide JS Usage

Who is online

Users browsing this forum: MSN [Bot] and 4 guests