May 5200612:00 AM CDT

Protect your code from spammers

Categories: PHP

A devious method of hijacking a form is to insert line breaks into form fields that will be used in email headers.

After the first line break, the spammer can insert a Bcc: line with a thousand email addresses (an arbitrary number, which could be more or less depending on how many addresses the spammer thinks your server can handle in one gulp).

After the Bcc: line of a thousand addresses, the spammer inserts two more line feeds, creating a blank line that tells the emailing software the end of the headers has been reached and the following content is to be the email message. All the spammer has to do now is inject the spam.

And the email with the spammer's spew is sent from your server to a thousand email addresses.

With automation, the spammer can submit your form over and over — to another thousand email addresses each time.

Not a pretty picture.

The Code

function _local_replace_bad($origvalue) {  // mail adress(ess) for reports...  
	$report_to = "YOUR_EMAIL_@_ADDRESS.com";
	// array holding strings to check, we do not trust these strings in $_POST
	$suspicious_str = array(
		"content-type:"
		,"charset="
		,"mime-version:"
		,"multipart/mixed"
		,"bcc:"
		,"cc:"
	);

	$suspect_found = false;

	// remove added slashes from $value...
	$value = stripslashes($origvalue);

	// checks if $value contains $suspect...
	foreach($suspicious_str as $suspect) {
		if(eregi($suspect, strtolower($value))) {
			/* if we found some suspicios string, 
			then we add our string, 
			so it will be messed a little bit. :) */
			$suspect_found = true;
			$value = eregi_replace($suspect, "(anti-spam-".$suspect.")", $value);
		}
	}

	if ($suspect_found) {
		/* if at least one suspicios string was found, then do something more
		Remember, that POST values were already changed.
		But we still want to inform our admin about this suspicios request.*/
		if(isset($report_to) && !empty($report_to)) {
			$ip = $_SERVER['REMOTE_ADDR'];
			$rf = $_SERVER['HTTP_REFERER'];
			$ua = $_SERVER['HTTP_USER_AGENT'];
			$ru = $_SERVER['REQUEST_URI'];
			$rm = $_SERVER['REQUEST_METHOD'];
			@mail($report_to,
"[ABUSE] [SUSPECT] @ " . $_SERVER['HTTP_HOST'] . " by " . $ip,
"Stopped possible mail-injection @ $_SERVER[HTTP_HOST] by $ip 
(".date('d/m/Y H:i:s').")
*** IP/HOST $ip 
*** USER AGENT $ua
*** REFERER $rf
*** REQUEST URI $ru
*** REQUEST METHOD $rm
*** SUSPECT
$value");
		} // if report
		$ip = (empty($_SERVER['REMOTE_ADDR'])) ? 'empty' : $_SERVER['REMOTE_ADDR'];
		$rf = (empty($_SERVER['HTTP_REFERER'])) ? 'empty' : $_SERVER['HTTP_REFERER'];
		$ua = (empty($_SERVER['HTTP_USER_AGENT'])) ? 'empty' : $_SERVER['HTTP_USER_AGENT'];
		$ru = (empty($_SERVER['REQUEST_URI'])) ? 'empty' : $_SERVER['REQUEST_URI'];
		$rm = (empty($_SERVER['REQUEST_METHOD'])) ? 'empty' : $_SERVER['REQUEST_METHOD'];
		// very often HTTP_USER_AGENT is empty. We consider this is 100% spam
		if ($suspect_found || $ua == "empty") {
			// exit the called script to stop the spammer.
			$value = "";
			exit();
		}
		// end if suscpect found
	}else{
		$value = $origvalue;
	}

	return($value);
}