Является ли эта функция 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
в коде это на самом деле не имеет значения.