Замена устаревшего eregi() на stristr(). Защищен ли этот почтовый скрипт php от инъекций заголовков?
Я уже много лет использую один и тот же php-скрипт для отправки электронных писем из контактных форм. Но когда мой веб-сервер обновился до php 5.3, вызов eregi вызывал отображение устаревших ошибок.
После поиска в Google я узнал, что могу использовать stristr вместо eregi.
Когда я делаю этот простой переключатель, все работает просто отлично, но я не мастер php, поэтому я хочу знать, по-прежнему ли мой скрипт защищен от инъекций заголовков.
Может кто-нибудь, пожалуйста, успокоить меня и подтвердите, что этот скрипт безопасен (или, по крайней мере, достаточно безопасен) для отправки электронных писем из контактной формы?
Вот пример текущего сценария с использованием stristr:
<?
$to="[email protected]";
// 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( "[email protected]", $fSub, $eBody, "From: Webmaster <[email protected]>");
exit(header("Location: http://www.mywebsite.com")); }
?>
ОБНОВЛЕНИЕ
Основываясь на всегда такой любезной помощи от cryptic, вот как выглядит мой новый сценарий. Как вы можете видеть, я удалил некоторые функции проверки заголовка вместо простой очистки полей ввода.
<?
$to="[email protected]";
// 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 answers
Вы пытаетесь занести в черный список заголовки, такие как BCC, CC, но не можете заблокировать ДО, ОТ.
RFC 822 на странице 16 в разделе 4.1 говорится:
Эта спецификация допускает несколько вхождений большинства полей. За исключением отмеченных случаев, их толкование здесь не указано, и их использование не рекомендуется.
Таким образом, злоумышленник сможет манипулировать сообщением, чтобы добавить дополнительных получателей и отправителей. Вам действительно следует просто проверять наличие новых строк и каретки возвращает или просто очищает все значения $_POST, удаляя символы \r и \n.
<?php
function clean_string($string)
{
return str_replace(array("\n", "\r"), '', $string);
}
$to = '[email protected]';
// 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.";
}
?>