I'm building a simple contact form for a website. It does not connect to a database, it just sends the email. Will this code prevent spammers from using header injections? Are there any vulnerabilities I'm not seeing?
//create short variable names
$name= filter_var($_POST['Name'],FILTER_SANITIZE_STRING);
$email= filter_var($_POST['Email'],FILTER_SANITIZE_STRING, FILTER_VALIDATE_EMAIL);
$subject= filter_var($_POST['Subject'],FILTER_SANITIZE_STRING);
$message= filter_var($_POST['Message'],FILTER_SANITIZE_STRING);
//set up some static information
$toaddress = 'blah@localhost.com,blahblah@localhost.com';
$mailcontent = "Customer name: ".$name."\n".
"Customer email: ".$email."\n".
"Subject: ".$subject."\n\n".
$message;
$fromaddress = "From:" . $email;
//invoke mail() function to send mail
mail($toaddress, "Website Contact Form",$mailcontent, $fromaddress);
?>
IMHO, your code is not secure, as you miss
\r
and\n
characters.filter_var()
only kills those, ifFILTER_SANITIZE_STRING
is used in conjunction withFILTER_FLAG_STRIP_LOW
, which will also filter out any characters below ASCII 32:Also,
FILTER_VALIDATE_MAIL
will return a true or false, which you also do not account for. I recommend to check out this excellent source forfilter_var()
, as the main PHP manual is very short on information.Update: As Alnitak pointed out, through the
\n\n
in the code, this actually doesn't matter.Nope, that doesn't sanitize anything.
It would be very very easy to fudge up that mailer.
I can add anything in a post value (that you read) to manipulate the mailer.
Header injection relies on being able to insert additional newlines into header variables, which makes the string look like a new header.
For example, allowing a subject value of
Testing\nCc: spamrecipient@example.com\n\nSome body text
would result in a message header containing:i.e. the abuser has not only added additional recipients, but they've managed to supply their own body text too.
However in your case the
$toaddress
is constant, and even if$toaddress
had been user-supplied it should be correctly sanitised by themail()
function.Your subject header is similarly constant
The
$message
variable is safe because by definition that's the body text and only sent after the real headers.That only leaves
$fromaddress
, and you're already usingFILTER_VALIDATE_EMAIL
on that which should also reject anything with a newline in it.However you should strictly be checking the result of that test, and aborting the whole thing if the result is
FALSE
. As it is if the validation fails thenmail()
will complain about being given a blankFrom:
address, but there's no header injection opportunity there.As far as I can tell, then, this code is actually secure.
Also, IMHO, you shouldn't send the emails from the user-supplied email address. That would fall foul of anti-spam mechanisms such as SPF.
You should use a constant
From:
value belonging to your own domain. If you like you could then use a correctly sanitised value in theReply-To
header to make it easier to have the subsequent reply go to the desired address.