Page 1 of 1

What security should I add to formmailer: what do you think?

Posted: Thu Apr 03, 2008 6:07 am
by ewwatson
Alright I upgraded my PHP formmailer - what do you think? Any tips? Any security holes I should fill on top of what is already in place? If so, where would you suggest placing them within the script below? Thanks!

Code: Select all

<?php
$mailto = 'youremail@gmail.com' ;
$from = "yourdomain.com Formmail" ;
$formurl = "http://www.yourdomain.com/formmail.php" ;
$errorurl = "http://www.yourdomain.com/formmailerror.php" ;
$thankyouurl = "http://www.yourdomain.com/thankyou.php" ;
 
$uself = 0;
 
$headersep = (!isset( $uself ) || ($uself == 0)) ? "\r\n" : "\n" ;
$name = $_POST['name'] ;
$email = $_POST['email'] ;
$subject = $_POST['subject'] ;
$comments = $_POST['comments'] ;
$http_referrer = getenv( "HTTP_REFERER" );
 
if (!isset($_POST['email'])) {
header( "Location: $formurl" );
exit ;
}
if (empty($name) || empty($email) || empty($subject) ||empty($comments)) {
header( "Location: $errorurl" );
exit ;
}
if ( ereg( "[\r\n]", $name ) || ereg( "[\r\n]", $email ) ) {
header( "Location: $errorurl" );
exit ;
}
 
if (get_magic_quotes_gpc()) {
$comments = stripslashes( $comments );
}
 
$message =
 
"This message was sent from:\n" .
"$http_referrer\n\n" .
 
"Name: $name\n\n" .
"Email: $email\n\n" .
"Subject: $subject\n\n" .
"comments: $comments\n\n" .
"\n\n------------------------------------------------------------\n" ;
 
mail($mailto, $from, $message,
"From: \"$name\" <$email>" . $headersep . "Reply-To: \"$name\" <$email>" . $headersep );
header( "Location: $thankyouurl" );
exit ;
 
?>
 
It outputs this

This message was sent from:
http://www.yourdomain.com/contact.php

Name: bob

Email: bob@gmail.com

Subject: easy

comments: easier!

Additionally, what do you think of these security measures? Good - bad? Should I add them to the script above or no? If so where? As you can see, all this this stuff is somewhat Greek to me. So I am in need of a professional eye that knows what all this mumbo-jumbo means!

Code: Select all

// Data cleaning function
function clean_data($string) {
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
$string = strip_tags($string);
return mysql_real_escape_string($string);
}
 
// Mail header removal
function remove_headers($string) {
$headers = array(
"/to\:/i",
"/from\:/i",
"/bcc\:/i",
"/cc\:/i",
"/Content\-Transfer\-Encoding\:/i",
"/Content\-Type\:/i",
"/Mime\-Version\:/i"
);
return preg_replace($headers, '', $string);
}
 
function remove_headers($string) {
$headers = array(
"/to\:/i",
"/from\:/i",
"/bcc\:/i",
"/cc\:/i",
"/Content\-Transfer\-Encoding\:/i",
"/Content\-Type\:/i",
"/Mime\-Version\:/i"
);
if (preg_replace($headers, '', $string) == $string) {
return $string;
} else {
die('You think I'm spammy? Spammy how? Spammy like a clown, spammy?');
}
}
 
// Mail header removal
function remove_headers($string) {
$headers = array(
"/to\:/i",
"/from\:/i",
"/bcc\:/i",
"/cc\:/i",
"/Content\-Transfer\-Encoding\:/i",
"/Content\-Type\:/i",
"/Mime\-Version\:/i"
);
$string = preg_replace($headers, '', $string);
return strip_tags($string);
}
 
// Pick up the cleaned form data
$name = remove_headers($_POST['name']);
$email = remove_headers($_POST['email']);
$topic = remove_headers($_POST['topic']);
$comments = remove_headers($_POST['comments']);

Re: What security should I add to formmailer: what do you think?

Posted: Wed Apr 09, 2008 4:45 am
by lafever
Let me know if you have found a solution/answer to this. I am working on a contact form on my page and would like to avoid header injections.

Additionally, I found a couple of functions at php.net

Code: Select all

 
 
/**
* Check single-line inputs:
* Returns false if text contains newline character 
*/
function has_no_newlines($text)
{
    return preg_match("/(%0A|%0D|\\n+|\\r+)/i", $text) == 0;
}
 
/**
* Check multi-line inputs:
* Returns false if text contains newline followed by
* email-header specific string
*/
function has_no_emailheaders($text)
{
    return preg_match("/(%0A|%0D|\\n+|\\r+)(content-type:|to:|cc:|bcc:)/i", $text) == 0;
}
 
 


Or even this function

Code: Select all

 
function contains_newlines($text)
{
 return preg_match("/(%0A|%0D|n+|r+)/i", $text);
}
 
How trusted are these functions?

I also think that additional measures should be taken to notify or create some type of log of these things trying to be injected.