Является ли эта функция 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
Нет, это не санирует ничего.
Было бы очень легко подделать эту почтовую программу.
Я могу добавить что-либо в значение сообщения (которое вы читаете), чтобы манипулировать почтовой программой.