I am trying to prevent mail header injection by looping through all the _POST data but the variables are not passing my validation. I have a few “date” fields that include slashes and some of the fields might be blank. Not sure if that would have anything to do with it. Can anyone see the problem with my logic? I keep getting my “fail” message. Thanks.
if(isset($_POST['submit'])) {
$boolValidateOK = 1;
function safe( $name ) {
return( str_ireplace(array( "\r", "\n", "%0a", "%0d", "Content-Type:", "bcc:","to:","cc:" ), "", $name ) );
}
foreach($_POST as $value){
if(!safe($value)){
$boolValidateOK = 0;
}else{
$boolValidateOK = 1;
}
}
if($boolValidateOK == 1){
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$to...etc
$subject...etc
$message...etc
mail($to, $subject, $message, $headers);
$success_message = "win";
}else{
$error_message = "fail";
}
}
What you’re doing is unnecessary. Note PHP’s
mail()function signature:The recipient is the second argument. The headers are all in the fourth argument. The contents of
$messageor$subjectare not going to magically “spill over” to the other arguments.Since your
$headersdoesn’t depend on user input, it doesn’t really matter if the user has entered. No such “injection” is possible. All you’re doing is butchering the message.PS: This code is wrong:
Think about it. Let’s say all your post values are not “safe,” but the last one iterated is. It will then overwrite
$boolValidateOKto1, and that’s the value it will retain by the time the loop has ended.Also, PHP does have a boolean type. If you have a bool, set them to
trueorfalseinstead of 1 and 0. It’s clearer.Regardless, I would recommend using something like PHPMailer. The native
mail()function is very awkward to use.