PHP and forms with a sprinkling of security

Recently one of my work collegues asked me to investigate some spam he was getting on his personal website account. These little challenges always intrigue me, so I said yes.

After much prodding in the email headers it became clear that the spammer was using a simple Contact from set up on the website.

Firstly I thought this problem down to the form using the POST method, and the PHP assuming the names of the form elements were assigned to global variables as it passed via the URL.

For example if the form looks thus:


<form name="silly_form" method="post" action="$php_self">
<input name="email"/>
</form>

Now when this form is submitted the PHP used to look like this:

<?php
if ($email)
{
mail("john@example.com", "Hi", $email);
}
?>

But that would work if you called the page like this:

http://example.com/page.php?email=fake@example.com

So the code was changed to this

<?php
if ($_POST['email'])
{
$email = $_POST['email'];
mail("john@example.com", "Hi", $email);
}
?>

But still the spam kept a coming….

This is becuase you can create a form in Javascript which can then be submitted, and it’s not too much of a jump to automate the creation of the form.

Here’s what the Javascript could look like:

<SCRIPT LANGUAGE="JavaScript">
function fnSubmit() {
document.emailform.submit();
return;
}
</SCRIPT>
<body LANGUAGE="javascript" onload="return fnSubmit()">
<form method="post" action="index.php" name="emailform">
Email: <input name="email" type="text" value="address"/><br />
<input type="submit" />
</form>

So we need a new approach, some kind of Turing test to make sure the user is human. I’m sure you’ve all seen the images that you can generate using either [CAPTCHA] or [the] [same] [idea]but it’s only a simple contact form.

So we developed a little piece of code that asks a user to enter two characters, that we tell them to enter and these are checked by the contact code. These characters are simple taken from two strings, one 32 characters long, and one 13 characters long. The current day and month are used to select the characters so they can be easily checked on the other side.


<?php
function GetCharacters()
{
// create the array
$day_string = "thirtytwocharactersjustincase";
$month_string = "thirteencharacters";
//
// get todays date
//
$day = date('d');
$month = date('m');
//
// get the array characters
//
$one = $day_string[$day];
$two = $month_string[$month];
// result
$result = $one . $two;
return($result);
}
// check characters
function CheckCharacters($a_characterArray)
{
// create the array
$day_string = "thirtytwocharactersjustincase";
$month_string = "thirteencharacters";
//
// get todays date
//
$day = date('d');
$month = date('m');
//
// get the characters
//
$characterOne = $day_string[$day];
$characterTwo = $month_string[$month];
$characterArray = $characterOne . $characterTwo;
//
// check the characters
//
if (0 == strcasecmp($a_characterArray, $characterArray))
{
return(true);
}
return(false);
}
?>

And there we have it, just enough Turing test for a contact form – enjoy…