Spam-proof email addresses on web sites

Over the weekend, I cobbled together another handy javascript method for foiling evil spam bots, whilst making life easy for web developers. The script below enables you to change the subject of the email as you go as well – you could add other variables like a link title too if you wished. Functions are very useful devices!

Firstly, the content of email.js:

function sibaem(subject) {
var username = "emailprefixhere";
var domain = "whatever.com";
var atsign = "@";
var address = username + atsign + domain;
document.write('<' + 'a' + ' ' + 'href=' + '"mailto:' + address + '?Subject=' + subject + '">');
}

Save the above as email.js in your scripts folder and link to it in the head of your document like this:

<script src="scripts/email.js" type="text/javascript"></script>

Then in the body of the document, call the function with the following code where you want an email to appear, for example:

<script type="text/javascript">
<!--
sibaem( "Website enquiry" );
document.write ( 'email me</a>' );
//-->
</script><noscript><a href='contact_form.php' title='Complete my contact form'>contact me</a></noscript>

If you wish to make the user changeable and for the email address to be visible to the human eye on your site, here’s the content of email.js:

function sibaem(username, subject) {
var domain = "whatever.com";
var atsign = "@";
var address = username + atsign + domain;
document.write('<' + 'a' + ' ' + 'href=' + '"mailto:' + address + '?Subject=' + subject + '">' + address + '</a>');
}

and here’s what goes in the body:

<script type="text/javascript">
<!--
sibaem( "youremailusername, Website enquiry" );
//-->
</script><noscript><a href='contact_form.php' title='Complete my contact form'>contact me</a></noscript>

Javascript Flash Detect Script

Place this code in a .js file and link it in the head of your document:

function FlashInstalled()
{
result = false;
if (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"])
{
result = navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;
}
else if (document.all && (navigator.appVersion.indexOf("Mac")==-1))
{
eval ('try {var xObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");if (xObj) result = true; xObj = null; } catch (e) {}');
}
return result;
}
function FlashWrite(url,width,height)
{
document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
document.write(' codebase="http://active.macromedia.com/flash4/cabs/swflash.cab#version=4,0,0,0" ');
document.write(' WIDTH=' + width + ' HEIGHT=' + height + '>');
document.write(' <PARAM NAME=movie VALUE="' + url + '"> <PARAM NAME=loop VALUE=false> <PARAM NAME=quality VALUE=best> <PARAM NAME=scale value=exactfit> <PARAM NAME=bgcolor VALUE=#CCFFFF> <PARAM NAME=menu value=false> ');
document.write(' <EMBED xsrc="' + url + '" quality=best bgcolor=#CCFFFF loop=false scale=exactfit menu=false ');
document.write(' swLiveConnect=FALSE WIDTH=' + width + ' HEIGHT=' + height);
document.write(' TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?
P1_Prod_Version=ShockwaveFlash">');
document.write(' </EMBED></OBJECT>');
}

You can call the above code flash.js file and link it in the head of your document like this:

<script language="JavaScript1.2" xsrc="flash.js" mce_src="flash.js" type="text/javascript"></script>

Then where you want your flash file to appear, place this code:

<script Language = "JavaScript" type="text/javascript">
if (FlashInstalled())
{
FlashWrite('images/flash/yourflashfile.swf',468,240);
}
else
{
var url = "linkyourflatimagetosomefile.php"
var image = "<img alt='Name of your flat image' xsrc='images/flash/yourstillimage.jpg' height=240 width=468 border=0>"
document.write(image.link(url));}</script>
<noscript><a xhref='linkyourflatimagetosomefile.php'><img alt='Name of your flat image' xsrc='images/flash/yourstillimage.jpg' height=240 width=468 border=0></a>
</noscript>

If the browser doesn’t have flash installed or doesn’t have java turned on, they will see yourstillimage.jpg instead of the flash file. Change the file width and height to match your .swf and image files.

Image protection with .htaccess

How to stop people stealing your images/bandwidth remotely:

(1) Make an image called dontsteal.gif and place it in a directory below the directory in which you are going to put the .htaccess file.

(2) Open notepad and copy this code … no hard carriage returns between lines.

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://whateverdomain.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.whateverdomain.com/.*$ [NC]
RewriteRule .*.(gif|GIF|jpg|JPG|zip|ZIP|png|PNG|swf|SWF)$ http://www.whateverdomain.com/dontsteal.gif [R,L]

(3) Change whateverdomain.com to whatever your domain is called.

(4) This code works with apache servers with mod_rewrite.

Obscuring email addresses from spammers

Here’s how to use an image and a .js script to disguise your email address from spam bot email collectors. This method splits the email address server side.

(1) Make an image of the email address you wish to use in .jpg, .gif or .png form.

(2) Creat a .js script as follows*:

var sb_domain = "yourdomain.com"
var sb_user = "whatever"
var sb_recipient = sb_user + "@" + sb_domain
var image = "<img alt='Contact Me' xsrc='images/e.png' height='11' width='166' style='margin-top:2px;border:0' />"
var sb_url = "mailto:" + sb_recipient
document.write(image.link(sb_url));

If you want to include a subject, use this code:

var sb_domain = "yourdomain.com"
var sb_user = "whatever"
var subject = "Whatever you like"
var sb_recipient = sb_user + "@" + sb_domain
var image = "<img alt='Contact Me' xsrc='images/e.png' height='13' width='187' style='vertical-align:bottom;border:0' />"
var sb_url = "mailto:" + sb_recipient + "?subject=" + escape(subject)
document.write(image.link(sb_url));

* The ‘/’ at the end of the image is for XHTML – if you are using HTML doctypes, leave it out.

(3) Save the file as whateveryoulike.js in your js includes directory or wherever you wish.

(4) Link to your .js script in the body of the page where you want it to appear as follows:

<script language="JavaScript" xsrc="directorywhereyousavedthescript/whateveryoulike.js" mce_src="directorywhereyousavedthescript/whateveryoulike.js" type="text/javascript"></script><noscript>Email Me</noscript>

Good luck in thwarting spammers!

PHP Form Script Security

Some ideas to tighten up form script security … more specifically to counter form spoofing and cross browser attacks.

(1) Check for extra _POST variables, and disallow any _GET variables.

{
$limit_post=count($_POST);
$limit_get=count($_GET);
if ($limit_post>8||$limit_get>0)
{
include ("formhead.php");
echo "Submission failed.";
include ("form2.php");
exit;
}
}

(2) Prevent the exceeding of maximum field length from the server side in the script – setting form field maximum length inputs is not sufficient.

{
$length = strlen($_POST['Name'] || $_POST['Email'] || $_POST['Address'] || etc);
if($length>30)
{
include ("formhead.php");
echo "Too many characters.";
include ("form2.php");
exit;
}
}

(3) Check for legal use of characters (white list approach).

{
if (eregi("[^-a-z]+$", $_POST['Name']) || eregi("[^-/.a-z0-9]+$", $_POST['Address']) || eregi("[^-a-z]+$", $_POST['City']) etc)
{
include ("formhead.php");
echo "Invalid characters.";
include ("form2.php");
exit;
}
}

(4) Check for well-formed email address.

{
if (!eregi("^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*$", $_POST['Email']))
{
include ("formhead.php");
echo "Please enter a valid email.";
$_POST['Email']="";
include ("form2.php");
exit;
}
}

(5) Use quotemeta to filter output (note that quotemeta doesn’t filter the pipe character – hence the productiveness of using the previous eregi function).

(6) Use the Session token method described at http://shiflett.org/archive/96 to further prevent XSS attacks.

eg.

In the document head:

<?php $token = md5(uniqid(rand(), true));
$_SESSION['token'] = $token; ?>

In the form:

<input type="hidden" name="sekret" value="<?php echo $token; ?>" />

In the script:

{
if ($_SESSION['token'] != $_POST['token'])
{
echo "Invalid submission.";
//go to error page
exit;
}
}

References:

http://phpsec.org/projects/guide/2.html
http://www.devshed.com/c/a/PHP/Reconsidering-PHP-variables/
http://au.php.net/manual/en/function.quotemeta.php
http://shiflett.org/

Countering form spam bot attacks

Spammers, the dregs of the internet, are now using automated bots to explore form security.

The bot completes the form to test for possible usage as a spam relay, attempting to inject extra headers which, if successful, will send the response to the bot owner.

To counter their tactics, fields like the mailto, from and subject fields can be checked server side (all user input should be checked server side).

eg.

mailto:

$to=$mailTo;
if ($to !== "youraddy@yourdomain.com")
{
die("Getawoollyoneupyah, spammer!");
}

from and subject fields:

if ((preg_match(' /[rn,;'"]/ ', $_POST['Email'])) || (preg_match(' /[rn,;'"]/ ', $mailSubject)))
{
die("Go away, spammer!");
}

Then, to prevent the bot filling in the form at all, the contact name field for example, can be checked as the bot attempts to fill in all fields with an email address.

elseif (eregi("[^-a-z ]", $_POST[Name]))
{
echo "Characters in name field are invalid.";
$_POST[Name] ="";
}

More information about the relevant email injection exploit can be found here:

http://computerbookshelf.com/email_injection/
http://securephp.damonkohler.com/index.php/Email_Injection

There’s a form testing script linked here as well as an explanation re asp scripts:

http://www.twologs.com/en/services/test/spamrelay.asp

and a script to ban known spam bots here:

http://www.foto50.com/spammercheck.phps