Как санировать ввод пользователя в PHP перед рассылкой?

У меня есть простой скрипт почтового PHP, который берет значения из формы, отправленной через POST, и отправляет их мне по почте:

<code><?php
$to = "[email protected]";

$name = $_POST['name'];
$message = $_POST['message'];
$email = $_POST['email'];

$body  =  "Person $name submitted a message: $message";
$subject = "A message has been submitted";

$headers = 'From: ' . $email;

mail($to, $subject, $body, $headers);

header("Location: http://example.com/thanks");
?>
</code>

Как я могу очистить вход?

 Carlos Lima29 июн. 2009 г., 12:11
@ Фрэнк Фармер: ты предлагаешь ему поверить, что никакой оскорбительный код не достигнет его кода только потому, что он использовал «прямое текстовое поле»? Это ужасный совет.
 Aaron Wallentine20 апр. 2016 г., 23:32
Для записи для тех, кто смотрит на это в будущем, утверждение @FrankFarmer неверно. Злоумышленник или кто-либо еще не ограничен использованием HTML-формы, которую вы создаете для отправки ваших данных. Есть много способов построить HTTP-запросы к сценарию, который обрабатывает вашу форму; Вы всегда должны предполагать, что любые данные могут попасть в любое поле.
 Frank Farmer28 июн. 2009 г., 20:46
Если вы используете прямое текстовое поле, в ваших данных $ _POST не должно быть никаких ошибок. Если вы используете какой-то текстовый редактор, который генерирует html, используйте html_entity_decode (). Обязательно уберите управляющие символы из темы - символы новой строки в теме могут испортить заголовки ваших писем
 Fiasco Labs30 янв. 2012 г., 05:14
Heh, прямое текстовое поле. Только что сделал XSS тест на того, кто это сделал. Им не понравилась забавная картинка, отправленная по ссылке img, введенной в «текстовом поле с прямыми линиями».

Ответы на вопрос(5)

Решение Вопроса

filter_var().

Пример здесь. Подобно

echo filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);   
 Haim Evgi28 июн. 2009 г., 21:01
php 5 довольно хороший filter_var (PHP 5> = 5.2.0)
 artlung28 июн. 2009 г., 20:55
Мне нравится filter_var, к сожалению, не все настройки хостинга имеют 5.2, но, похоже, это хорошо продуманная функция.
 markus22 авг. 2014 г., 00:48
Не все хостинг-версии имеют 5,2, хе-хе, это так, 2009 год. Теперь больше похоже, что они все еще работают с 5,4, они подозрительны.
 Aaron Wallentine20 апр. 2016 г., 23:46
Убедитесь, что вы ничего не передаете функции mail () особенн параметр $ headers) может содержать нефильтрованный текст, особенно\r\n(header): (...);

artlungтвет выше @ для подтверждения адреса электронной почты ..

Я использую этот вид кода для предотвращения внедрения заголовка ..

// define some mail() header's parts and commonly used spam code to filter using preg_match
$match = "/(from\:|to\:|bcc\:|cc\:|content\-type\:|mime\-version\:|subject\:|x\-mailer\:|reply\-to\:|\%0a|\%0b)/i";

// check if any field's value containing the one or more of the code above
if (preg_match($match, $name) || preg_match( $match, $message) || preg_match( $match, $email)) {

// I use ajax, so I call the string below and send it to js file to check whether the email is failed to send or not
echo "failed";

// If you are not using ajax, then you can redirect it with php header function i.e: header("Location: http://example.com/anypage/");

// stop the script before it reach or executing the mail function
die();

}

Themail()ышеуказанная фильтрация заголовков @ слишком строгая, поскольку некоторые пользователи могут использовать отфильтрованные строки в своем сообщении без какого-либо намерения перехватить форму электронной почты, поэтому перенаправьте ее на страницу, объясняющую, какие строки запрещены в Форма или объяснить это на странице формы.

предоставленного пользователями в $ headers, который передается mail () ($ email в вашем случае)! Видеть Инъекция по электронной почте.

PHP должен позаботиться о дезинфекции $ to и $ subject, но есть версии PHP с ошибками (Затронуты PHP 4 <= 4.4.6 и PHP 5 <= 5.2.1, см. MOPB-34-2007).

единственная релевантная проверка, которую я вижу для этих входных данных, это проверка электронной почты для $ _POST ["email"] и, возможно, буквенно-цифровой фильтр для других полей, если вы действительно хотите ограничить область действия сообщения.

Чтобы отфильтровать адрес электронной почты, просто используйте Filter_var:

$email = filter_var($email, FILTER_SANITIZE_EMAIL);

По предложению Фрэнка Фармера вы также можете отфильтровывать новые строки в теме письма:

$subject = str_replace(array("\r","\n"),array(" "," "),$subject);
 Frank Farmer28 июн. 2009 г., 20:49
Символы новой строки в темах электронной почты несколько проблематичны.
 Wadih M.28 июн. 2009 г., 20:58
Привет, Фрэнк, я отредактировал свой ответ, чтобы отразить твое предложение.
 Cheekysoft29 июн. 2009 г., 12:03
В зависимости от того, как точно построено электронное письмо, в любой заголовок электронной почты можно вставлять символы новой строки, позволяя злоумышленнику добавлять любые новые или заменяющие заголовки электронных писем, которые ему нравятся. В дополнение к этому, вставка целой пустой строки (две строки) позволяет злоумышленнику вставить тело письма по своему выбору, полностью перекрывая сгенерированное письмо.

filter_var отлично. Если он недоступен, добавьте его в свою панель инструментов.

The$headersеременная @ особенно плоха в плане безопасности. Это может быть добавлено и вызвать поддельные заголовки, которые будут добавлены. Этот пост называется Email Injection обсуждает это очень хорошо.

filter_var i отлично, но еще один способ убедиться, что что-то является адресом электронной почты, а не чем-то плохим, - это использоватьisMail() функция. Вот один из них:

function isEmail($email) {
    return preg_match('|^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$|i', $email);
};

Чтобы использовать это, вы можете сделать:

if (isset($_POST['email']) && isEmail($_POST['email'])) {
    $email = $_POST['email'] ;
} else {
    // you could halt execution here, set $email to a default email address
    // display an error, redirect, or some combination here,
}

С точки зрения ручной проверки, ограничения длины с помощьюsubstr(), Бегstrip_tags() и иным образом ограничивая то, что можно вставить.

 user262999813 янв. 2015 г., 12:29
Говоря о filter_var, у него также есть фильтр для проверки писем, поэтому вашisEmailункция @ плохая и ненужная (не говоря уже о том, что регулярное выражение не может правильно проверять электронную почту).

Ваш ответ на вопрос