Blocks comment spam with non-captcha methods.
The extension adds 3 options to PunBB's administrative settings panel:
1. Stop posting over proxies of the transparent type.
This proxy type is usually abused by spammers. It is preferred over the anonymous type, probably because the latter type often is slow and only accessible through web-interfaces. This method of comment spam blocking works surprisingly good in many cases - and still allows forum visitors to use anonymous proxies without limitations. Almost the same method is used by Google to protect their servers, in that you are not allowed to start a search without solving a captcha. Remeber that the anonymous type is not blocked, only the transparent one.
2. Prevent posting from clients that do not send the accept-language header (every bowser sends this header, but spammers sometimes hide it completely).
3. Insert a spammer trap in post.php (a hidden dummy form) - only bots can see it. Thus most bots cannot abuse the post form. They are blocked before they reach the real form. Only the most recent IP's from bots that used the hidden form are stored- the oldest are deleted.
This extension might be useful for those who are looking for a captcha alternative or for those looking for additional spam protection.
You would need to create two files as follows.
- the yasb extension folder should contain manifest.xml with:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE extension SYSTEM "ext-1.0.dtd">
<!--
/**
* Yet another spam blocker (YASB - a non captcha alternative)
*
* @package yasb
*/
-->
<extension engine="1.0">
<id>yasb</id>
<title>Yet another spam blocker (YASB - a non captcha alternative)</title>
<version>1.1</version>
<description>Blocks comment spam with non-captcha methods:
1. Stops posting over the transparent proxy type (this type is usually abused by spammers) but allows the anonymous web proxies maybe used by your forum visitors.
2. Prevents posting from browsers not sending an accept-language header (every bowser sends this header, but spammers often try to hide the originating country).
3. Inserts a spammer trap through a hidden form in post.php - only bots can see it. Thus many bots are blocked from using the post form. Only the most recent IP's that used the hidden form are stored, so the blocked IP's will expire automatically.
</description>
<author>NettiCat</author>
<minversion>1.3</minversion>
<maxtestedon>1.3.4</maxtestedon>
<install>
<![CDATA[
$new_config = array(
'o_yasb_block_proxy' => '1',
'o_yasb_block_missing_language' => '1',
'o_yasb_spamtrap' => '1'
);
foreach($new_config as $conf_name => $conf_value)
{
if (!array_key_exists($conf_name, $forum_config))
{
$query = array(
'INSERT' => 'conf_name, conf_value',
'INTO' => 'config',
'VALUES' => '\''.$conf_name.'\', \''.$conf_value.'\''
);
$forum_db->query_build($query) or error(__FILE__, __LINE__);
}
}
]]>
</install>
<uninstall>
<![CDATA[
$query = array(
'DELETE' => 'config',
'WHERE' => 'conf_name in (\'o_yasb_block_proxy\', \'o_yasb_block_missing_language\', \'o_yasb_spamtrap\')',
);
$forum_db->query_build($query) or error(__FILE__, __LINE__);
]]>
</uninstall>
<hooks>
<hook id="po_start"><![CDATA[
$fname = ".htbots"; //bot IP's file
//is the IP an already known bot? compare with saved IP's
if (file_exists($fname) && $forum_config['o_yasb_spamtrap'] == '1')
{
$lines = file($fname);
foreach($lines as $line)
{
if(trim($line) == $_SERVER['REMOTE_ADDR']){
//known bot has gone into trap
echo "403 Forbidden - Your IP is listed as known spam bot\n";
header("HTTP/1.0 403 Forbidden");
exit;
}
}
}
//yet unknown bot has gone into trap
if (isset($_GET['trap']) && $forum_config['o_yasb_spamtrap'] == '1')
{
//read saved bot IP list
if (file_exists($fname)) {
$lines = file($fname);
}else{
$lines = array();
}
//trim list
while(count($lines) > 100) {
array_shift($lines);
}
//add new bot IP
array_push($lines, $_SERVER['REMOTE_ADDR']);
//save updated list to public file
$fhandle = fopen($fname,"w");
foreach($lines as $key => $value){
fwrite($fhandle,trim($value)."\n");
}
fclose($fhandle);
echo "403 Forbidden - It seems you are a spam bot\n";
header("HTTP/1.0 403 Forbidden");
exit;
}
//check request headers
$headers = getallheaders();
$acceptlang = "";
while (list ($header, $value) = each ($headers)) {
if($forum_config['o_yasb_block_proxy'] == '1' && (stristr($header, 'FORWARD') == TRUE || stristr($header, 'PROX') == TRUE || stristr($header, 'VIA') == TRUE
|| stristr($header, 'REMOTE') == TRUE || stristr($header, 'CLIENT-IP') == TRUE)) {
echo "403 Forbidden - Posting via PROXY is not allowed, please use a direct connection (anti-spam protection)\n";
header("HTTP/1.0 403 Forbidden");
exit;
}
if(stristr($header, 'ACCEPT-LANGUAGE') == TRUE) {
$acceptlang = $value;
}
}
//does accept language exist?
if($forum_config['o_yasb_block_missing_language'] == '1' && $acceptlang == "") {
echo "403 Forbidden - Missing browser accept language (anti-spam protection)\n";
header("HTTP/1.0 403 Forbidden");
exit;
}
]]>
</hook>
<hook id="po_main_output_start, vt_qpost_output_start">
<![CDATA[
//create hidden form as bot trap
?>
<!-- spam trap begin -->
<div style='display: none;'>
<form action='post.php?trap=1' method='post'><br>
<input name='email' value='email'/><br>
<input name='homepage' value='homepage'/><br>
<input name='url' value='url'/><br>
<textarea name='comment'></textarea><br>
</form>
</div>
<!-- spam trap end -->
<?php
]]>
</hook>
<hook id="aop_setup_validation">
<![CDATA[
if (!isset($form['yasb_block_proxy']) || $form['yasb_block_proxy'] != '1')
$form['yasb_block_proxy'] = '0';
if (!isset($form['yasb_block_missing_language']) || $form['yasb_block_missing_language'] != '1')
$form['yasb_block_missing_language'] = '0';
if (!isset($form['yasb_spamtrap']) || $form['yasb_spamtrap'] != '1')
$form['yasb_spamtrap'] = '0';
]]>
</hook>
<hook id="aop_setup_personal_fieldset_end">
<![CDATA[
if (file_exists($ext_info['path'].'/lang/'.$forum_user['language'].'/'.$ext_info['id'].'.php'))
require $ext_info['path'].'/lang/'.$forum_user['language'].'/'.$ext_info['id'].'.php';
else
require $ext_info['path'].'/lang/English/'.$ext_info['id'].'.php';
$forum_page['group_count'] = $forum_page['item_count'] = 0;
?>
<div class="content-head">
<h2 class="hn"><span><?php echo $lang_yasb['Setup'] ?></span></h2>
</div>
<fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
<legend class="group-legend"><strong><?php echo $lang_yasb['Setup description legend'] ?></strong></legend>
<div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
<div class="sf-box checkbox">
<label for="fld<?php echo $forum_page['fld_count'] ?>">
<span><?php echo $lang_yasb['Proxy'] ?></span>
<?php echo $lang_yasb['Proxy help'] ?>
</label>
<span class="fld-input"><input type="checkbox" id="fld<?php echo ++$forum_page['fld_count'] ?>" name="form[yasb_block_proxy]" value="1" <?php if ($forum_config['o_yasb_block_proxy'] == '1') echo ' checked="checked"' ?>/></span>
</div>
</div>
<div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
<div class="sf-box checkbox">
<label for="fld<?php echo $forum_page['fld_count'] ?>">
<span><?php echo $lang_yasb['Language'] ?></span>
<?php echo $lang_yasb['Language help'] ?>
</label>
<span class="fld-input"><input type="checkbox" id="fld<?php echo ++$forum_page['fld_count'] ?>" name="form[yasb_block_missing_language]" value="1" <?php if ($forum_config['o_yasb_block_missing_language'] == '1') echo ' checked="checked"' ?>/></span>
</div>
</div>
<div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
<div class="sf-box checkbox">
<label for="fld<?php echo $forum_page['fld_count'] ?>">
<span><?php echo $lang_yasb['Trap'] ?></span>
<?php echo $lang_yasb['Trap help'] ?>
</label>
<span class="fld-input"><input type="checkbox" id="fld<?php echo ++$forum_page['fld_count'] ?>" name="form[yasb_spamtrap]" value="1" <?php if ($forum_config['o_yasb_spamtrap'] == '1') echo ' checked="checked"' ?>/></span>
</div>
</div>
</fieldset>
<?php
]]>
</hook>
</hooks>
</extension>
....and the lang/english folder should contain yasb.php with:
<?php
if (!defined('FORUM')) die();
$lang_yasb = array(
'Setup' => 'YASB Spam Protection',
'Setup description legend' => 'Configure Spam Protection',
'Proxy' => 'Block transparent proxies',
'Proxy help' => 'If checked, any attempt to post via a non-anonymous proxy is rejected.',
'Language' => 'Block posts with missing language header',
'Language help' => 'If checked, posts from clients that do not send the accept language header will be rejected.',
'Trap' => 'Activate spammer trap',
'Trap help' => 'If checked, a invisible dummy form is created - any bot that uses the form is added to a temporary IP blacklist and cannot access post.php'
)
?>
YASB spammer trap would create a bot-IP plain text file named .htbots in the forum folder. You might want to make it public/share otherwise deny access by defining a .htaccess rule e.g.
<FilesMatch "^\.htbots">
Order allow,deny
Deny from all
</FilesMatch>