Stopping Pivot Account Malfeasants ::: SPAM
I have been running Pivot for my VAXman's Musings Soapbox blogging site for about a year and a half. It has been working very well for me; however, one of the things that has been most annoying about Pivot is its lack of any functional mechanisms to keep the SPAMmers from registering for accounts. Several other software packages used on the sites that I run and or maintain have had hooks into the StopForumSpam database site. The StopForumSpam site functions as a rather effective blocker of SPAMmer account registrations. Until now, however, there have been no plugins or extensions available for Pivot to perform this same function. I recently upgraded Pivot on my OpenVMS Alpha to version 1.40.8 Dreadwind. Unfortunately, this latest release had still not added any hooks into the StopForumSpam database. I recently added a plugin for vBulletin (called vbStopForumSpam) which has been working remarkable well. So, I decided to attack this same problem of SPAMmer account applications within Pivot for myself. Life is just too short to waste it on dealing with SPAMmer scum.I did a bit of perusing through the Pivot PHP code on my Alpha hosting this site. I quickly determined where in the code I would need to add a hook to the StopForumSpam database. That code was the
reg_user()
function in the file module_userreg.php. That code looks like this:
function reg_user($user)
{
global $Cfg, $Paths, $Current_weblog;
$name_md5 = strtolower(md5(strtolower($user['name'])));
if (save_serialize($Paths['pivot_path'].'db/users/'.$name_md5.'.php', $user))
{
printf("<h2>%s</h2>\n\n", lang('commentuser', 'user_stored'));
}
else
{
printf("<h2>%s</h2>\n\n", lang('commentuser', 'user_stored_failed'));
}
$self= $Paths['host'] . $_SERVER['PHP_SELF'];
$mail1 = lang('commentuser', 'registered')."\n\n";
$mail2 = lang('commentuser', 'reg_verify_long')."\n\n";
$url = sprintf("%s?func=verify&name=%s&code=%s&w=%s", $self,
urlencode($user['name']), md5($user['pass']."email"), para_weblog($Current_weblog));
$mail = sprintf($mail1.$mail2, $Cfg['sitename'], $url );
if (!mail($user['email'], "[Pivot] ".lang('commentuser','reg_confirmation'),
$mail, "From: ".$user['email']))
{
$mail2 = '<a href="%s">'.lang('commentuser','reg_verify_short').'</a>';
$mail = sprintf($mail1.$mail2, $Cfg['sitename'], $url );
echo "\n<br />". nl2br($mail) ."<br />\n";
}
else
{
echo sprintf(lang('commentuser','reg_verification'), $user['email']);
}
notify_new('visitor_registration', array('add',$user['name']));
}
Since this code takes the supplied user registration info and creates the database entry, this information must first be checked against the StopForumSpam database. So, the logical place to insert this test is at the very beginning of this function.
The StopForumSpam database's API is very simple — Pass it a formatted URL with the applicant's username, email and IP address to StopForumSpam. The URL must look like this:
http://stopforumspam.com/api?ip=aa.bb.cc.dd&username=username&email=email
StopForumSpam site responds with the following information when it receives a properly formatted URL request.
<response success="true">
<type>ip</type>
<appears>yes or no</appears>
<frequency>count</frequency>>
<lastseen>yyyy-mm-dd hh:mm:ss</lastseen> # if <appears> is yes
<type>email</type>
<appears>yes or no</appears>
<frequency>count</frequency>
<lastseen>yyyy-mm-dd hh:mm:ss</lastseen> # if <appears> is yes
<type>username</type>
<appears>yes or no</appears>
<frequency>count</frequency>
<lastseen>yyyy-mm-dd hh:mm:ss</lastseen> # if <appears> is yes
</response>
The task is now fairly straightforward:
- compose the URL
- send it as an HTTP request
- capture the HTTP response
- parse it for database appearance
- if it appears, it's a SPAMmer
require
statement.
require dirname(dirname(__FILE__))."/classes/HTTPRequest.class.php";
The
reg_user()
function code was then modified from its original (shown above) with the following code (the new code added is shown as red text):
function reg_user($user)
{
global $Cfg, $Paths, $Current_weblog;
$ipadd=$_SERVER['REMOTE_ADDR'];
$email=urlencode($user['email']);
$uname=urlencode($user['name']);
$q = "http://www.stopforumspam.com/api?ip=".$ipadd."&email=".$email.
"&username=".$uname;
$r = new HTTPRequest($q);
$s = $r->DownloadToString();
unset($r);
if (strpos($s,'<appears>yes</appears>'))
{
echo '<div align="center">';
echo '<img src="/pivot/pics/SPAMmer.gif" alt="SPAMmer">';
echo '</div>';
return FALSE;
}
$name_md5 = strtolower(md5(strtolower($user['name'])));
if (save_serialize($Paths['pivot_path'].'db/users/'.$name_md5.'.php', $user))
{
printf("<h2>%s</h2>\n\n", lang('commentuser', 'user_stored'));
}
else
{
printf("<h2>%s</h2>\n\n", lang('commentuser', 'user_stored_failed'));
}
$self= $Paths['host'] . $_SERVER['PHP_SELF'];
$mail1 = lang('commentuser', 'registered')."\n\n";
$mail2 = lang('commentuser', 'reg_verify_long')."\n\n";
$url = sprintf("%s?func=verify&name=%s&code=%s&w=%s", $self,
urlencode($user['name']), md5($user['pass']."email"), para_weblog($Current_weblog));
$mail = sprintf($mail1.$mail2, $Cfg['sitename'], $url );
if (!mail($user['email'], "[Pivot] ".lang('commentuser','reg_confirmation'),
$mail, "From: ".$user['email']))
{
$mail2 = '<a href="%s">'.lang('commentuser','reg_verify_short').'</a>';
$mail = sprintf($mail1.$mail2, $Cfg['sitename'], $url );
echo "\n<br />". nl2br($mail) ."<br />\n";
}
else
{
echo sprintf(lang('commentuser','reg_verification'), $user['email']);
}
notify_new('visitor_registration', array('add',$user['name']));
}
I found a small graphic on the net and I have employed it to signal to the user attempting to register that he or she has been identified as a SPAMmer. If the StopForumSpam database contains one or more pieces of information identifying this user account applicant as a SPAMmer, the following graphic will be displayed.