Picture of Paul Silver

Paul Silver

Making websites for companies and helping advertise them

E-mail contact form spam checking code for PHP

I have been having problems with people using the contact forms on some of my PHP sites to send spam messages to me and other people. This is done through 'e-mail injection' and works even if the receiving address is hardcoded (which mine are.)

I've noticed that all the spams have a few things in common, they have words like 'Content-Type:', 'cc:', and 'bcc:' in them. I decided to check my form fields for words like that, and if they come through I don't send the mail. Below is the function I came up with to check for these words that indicate spamming, and at the bottom of this page is an alternative.


Checking function

Put this function somewhere on the PHP code section of your page, or call it in with require_once:

NB: This code works if the form information is being sent through action="post"

// Function to check for spam
function checkforspam() {
   $problem = 'N';
   foreach ($_POST as $key => $value) {
     if (stristr($value,'Content-Type:') || stristr($value,'bcc:')) {
       $problem = 'Y';
     }
   }
   if ($problem == 'Y') {
     return 'Y';
   } else {
     return 'N';
   }
}

When you run checkforspam() it will give back Y or N for whether it thinks the form is being injected with spam or not.


Code to trigger the check

Call it using this code when you want to check for spam:

if (checkforspam() == 'N') {

// Your mail code here

}


Code explanation

I set $problem = 'N'; so I can check at the end to see if a problem have been found or not.

foreach ($_POST as $key => $value) { loops through each form field that has been sent to the page. Then if (stristr($value,'Content-Type:') || stristr($value,'bcc:')) { checks if 'Content-Type:' or 'bcc:' in any case (upper or lower) exist in the form field.

If the words do exist, $problem is set to 'Y'. Then if ($problem == 'Y') { checks if it's Y and sets the return of the function depending on it.

When you run checkforspam() it will give back Y or N for whether it thinks the form is being injected with spam or not.


Alternative function

Matt points out you could instead use the following for the function:

function checkforspam() {
  if ( preg_match( "/bcc:|Content-Type:/i", implode( $_POST ) ) ){
    return 'Y';
   } else {
     return 'N';
   }
}

Which is a damn sight more elegant and shorter. This in part explains why he writes books on PHP whereas I read them.

More code articles


Paul Silver. September 2005

© 2024 Paul Silver & Silver Web Services Ltd