问题
I've been using the same php script to send emails from contact forms for years. But when my web server upgraded to php 5.3 the call to eregi was causing deprecated errors to display.
After a Google search I learned that I could use stristr instead of eregi.
When I make this simple switch everything works just fine, but I'm no php wizard so I want to know if my script is still secure from header injections.
Can someone please put my mind at ease and confirm that this script is safe (or at least safe enough) to use for sending emails from a contact form?
Here is an example of the current script with stristr in use:
<?
$to="myemail@gmail.com";
// the $Name is the PHP variable, the _Post['Name'] should match the name of the input boxes in the form
$Name=$_POST['Name'];
$Email=$_POST['Email'];
$Phone=$_POST['Phone'];
$Message=$_POST['Message'];
// you can format the email anyway you want.
$message="Form submitted by $Name
Applicant Information:\n
Name: $Name
Email: $Email
Phone: $Phone
Message: $Message";
// Check for script HiJack
$arBadStr = array("Content-Type:", "MIME-Version:", "Content-Transfer-Encoding:", "bcc:", "cc:");
foreach($_POST as $tName => $tVal){
foreach($arBadStr as $tStr){
if(stristr($tStr, $tVal)){
$fSub = "Failed: Header Injection.";
reportError($fSub);
}}}
if(mail($to,"mywebsite.com contact Form Submission",$message,"From: $Name <$Email>")) {
echo "Thank you $Name for your interest. We will contact you shortly";
} else {
echo "There was a problem sending the mail. Please check that you filled in the form correctly.";
}
// Report error function called when test detects hijacking. Mails report to webmaster and kills process.
function reportError($fSub) {
while(list($name, $value) = each($_POST)) {
$eBody .= "$name : $value \n\r"; }
mail( "myemail@gmail.com", $fSub, $eBody, "From: Webmaster <myemail@gmail.com>");
exit(header("Location: http://www.mywebsite.com")); }
?>
UPDATE
Based on the ever-so-gracious help from cryptic this is what my new script looks like. As you can see I've stripped out some of the header validation functions in place of simply sanitizing the input fields.
<?
$to="myemail@gmail.com";
// the $Name is the PHP variable, the _Post['Name'] should match the name of the input boxes in the form
$Name = str_replace(array("\n", "\r"), '', $_POST['Name']);
$Email = str_replace(array("\n", "\r"), '', $_POST['Email']);
$Phone = str_replace(array("\n", "\r"), '', $_POST['Phone']);
$Message = str_replace(array("\n", "\r"), '', $_POST['Message']);
function clean_string($string) {
$bad = array("content-type","bcc:","to:","cc:","href");
return str_replace($bad,"",$string);
}
$Name = clean_string($Name);
$Email = clean_string($Email);
$Phone = clean_string($Phone);
$Message = clean_string($Message);
// you can format the email anyway you want.
$message="Form submitted by $Name
Applicant Information:\n
Name: $Name
Email: $Email
Phone: $Phone
Message: $Message";
if(mail($to,"mywebsite.com contact Form Submission",$message,"From: $Name <$Email>")) {
echo "Thank you $Name for your interest. We will contact you shortly";
} else {
echo "There was a problem sending the mail. Please check that you filled in the form correctly.";
}
?>
回答1:
You try to blacklist headers like BCC, CC but fail to block TO, FROM.
RFC 822 on page 16 in section 4.1 it states:
This specification permits multiple occurrences of most fields. Except as noted, their interpretation is not specified here, and their use is discouraged.
So an attacker would be able to manipulate the message to add additional recipients and senders. You should really just be checking for newlines and carriage returns or just sanitize all the $_POST values by stripping out \r and \n characters.
<?php
function clean_string($string)
{
return str_replace(array("\n", "\r"), '', $string);
}
$to = 'myemail@gmail.com';
// the $Name is the PHP variable, the _Post['Name'] should match the name of the input boxes in the form
$Name = clean_string($Name);
$Email = clean_string($Email);
$Phone = clean_string($Phone);
$Message = clean_string($Message);
// you can format the email anyway you want.
$message = "Form submitted by $Name
Applicant Information:\n
Name: $Name
Email: $Email
Phone: $Phone
Message: $Message";
if (mail($to, 'mywebsite.com contact Form Submission', $message, "From: $Name <$Email>"))
{
echo 'Thank you ' . htmlspecialchars($Name) . ' for your interest. We will contact you shortly';
}
else
{
echo "There was a problem sending the mail. Please check that you filled in the form correctly.";
}
?>
来源:https://stackoverflow.com/questions/13773451/replacing-deprecated-eregi-with-stristr-is-this-php-mail-script-secure-from