Является ли эта функция 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 = 'blah@localhost.com,blahblah@localhost.com';
$mailcontent = "Customer name: ".$name."n".
"Customer email: ".$email."n".
"Subject: ".$subject."nn".
$message;
$fromaddress = "From:" . $email;
//invoke mail() function to send mail
mail($toaddress, "Website Contact Form",$mailcontent, $fromaddress);
?>
3 ответа:
Инъекция заголовка основана на возможности вставки дополнительных новых строк в переменные заголовка, что делает строку похожей на новый заголовок.
Например, разрешение значения субъекта
Testing\nCc: spamrecipient@example.com\n\nSome body textприведет к заголовку сообщения, содержащему:То есть злоумышленник не только добавил дополнительных получателей, но и сумел снабдить их собственным текстом.Subject: Testing Cc: spamrecipient@example.com Some body textОднако в вашем случае
$toaddressявляется постоянным, и даже если$toaddressбыл предоставлен пользователем, он должен быть правильно санируется функциейmail().Ваш заголовок темы аналогично постоянен
Переменная
$messageбезопасна, потому что по определению это основной текст и передается только после реальных заголовков.Это только оставляет
Однако вы должны строго проверять результат этого теста и прерывать все дело, если результат будет$fromaddress, и вы уже используетеFILTER_VALIDATE_EMAILна том, что должно также отклонять что-либо с новой строкой в нем.FALSE. Как это бывает, если проверка завершается неудачей, тогдаmail()будет жаловаться на то, что ему дали пустой адресFrom:, но там нет возможности ввода заголовка.насколько я могу судить, этот код действительно безопасен.
Кроме того, ИМХО, вы не должны отправлять электронные письма с указанного пользователем адреса электронной почты. Это было бы нарушением антиспамовых механизмов, таких как SPF.
Вы должны использовать значение константы
From:, принадлежащее вашему собственному домену. Если вы хотите, вы могли бы использовать правильно санированное значение в заголовкеReply-To, чтобы облегчить отправку последующего ответа по нужному адресу.
ИМХО, ваш код не защищен, так как вы пропускаете символы
\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в коде это на самом деле не имеет значения.