Является ли эта функция mail() безопасной от вставки заголовка?

Я создаю простую контактную форму для веб-сайта. Он не подключается к базе данных, он просто отправляет электронное письмо. Будет ли этот код мешать спамерам использовать инъекции заголовков? Есть ли какие-либо уязвимости, которых я не вижу?   

//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 = '[email protected],[email protected]';

$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);
?>

Ответ 1

Ввод заголовка зависит от возможности вставки дополнительных строк новой строки в переменные заголовка, что делает строку похожей на новый заголовок.

Например, допустимое значение объекта Testing\nCc: [email protected]\n\nSome body text приведет к заголовку сообщения, содержащему:

Subject: Testing
Cc: [email protected]

Some body text

то есть. злоумышленник не только добавил дополнительных получателей, но и сам смог предоставить собственный текст тела.

Однако в вашем случае $toaddress является константой, и даже если $toaddress был предоставлен пользователем, он должен быть правильно дезинфицирован функцией mail().

Заголовок темы аналогичен константе

Переменная $message безопасна, поскольку по определению это текст тела и отправляется только после реальных заголовков.

Это оставляет только $fromaddress, и вы уже используете FILTER_VALIDATE_EMAIL для того, что должно также отвергать что-либо с новой строкой в ​​нем.

Однако вы должны строго проверить результат этого теста и прервать все это, если результат FALSE. Как бы то ни было, если проверка не удалась, то mail() будет жаловаться на то, что ему был дан пустой адрес From:, но там нет возможности вставки заголовка.

Насколько я могу судить, этот код действительно безопасен.


Кроме того, IMHO, вы не должны отправлять электронные письма с предоставленного пользователем электронного адреса. Это могло бы испортить механизмы защиты от спама, такие как SPF.

Вы должны использовать постоянное значение From:, принадлежащее вашему собственному домену. Если вам нравится, вы можете использовать правильно обработанное значение в заголовке Reply-To, чтобы упростить последующий ответ на нужный адрес.

Ответ 2

IMHO, ваш код небезопасен, так как вы пропускаете символы \r и \n. filter_var() только убивает их, если FILTER_SANITIZE_STRING используется в сочетании с FILTER_FLAG_STRIP_LOW, который также отфильтровывает любые символы под ASCII 32:

$message= filter_var($_POST['Message'], 
                     FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);

Кроме того, FILTER_VALIDATE_MAIL вернет значение true или false, которое вы также не учитываете. Я рекомендую проверить этот отличный источник для filter_var(), так как основное руководство по PHP очень мало информации.


Обновление: Как отметил Алнитак, через \n\n в коде это не имеет значения.

Ответ 3

Нет, это не санирует ничего.

Было бы очень легко подделать эту почтовую программу.

Я могу добавить что-либо в значение сообщения (которое вы читаете), чтобы манипулировать почтовой программой.