Вопрос по php, sanitize, security, email – Как санировать ввод пользователя в PHP перед рассылкой?

44

У меня есть простой скрипт почтового 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>

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

Если вы используете прямое текстовое поле, в ваших данных $ _POST не должно быть никаких ошибок. Если вы используете какой-то текстовый редактор, который генерирует html, используйте html_entity_decode (). Обязательно уберите управляющие символы из темы - символы новой строки в теме могут испортить заголовки ваших писем Frank Farmer
@ Фрэнк Фармер: ты предлагаешь ему поверить, что никакой оскорбительный код не достигнет его кода только потому, что он использовал «прямое текстовое поле»? Это ужасный совет. Carlos Lima
Heh, прямое текстовое поле. Только что сделал XSS тест на того, кто это сделал. Им не понравилась забавная картинка, отправленная по ссылке img, введенной в «текстовом поле с прямыми линиями». Fiasco Labs
Для записи для тех, кто смотрит на это в будущем, утверждение @FrankFarmer неверно. Злоумышленник или кто-либо еще не ограничен использованием HTML-формы, которую вы создаете для отправки ваших данных. Есть много способов построить HTTP-запросы к сценарию, который обрабатывает вашу форму; Вы всегда должны предполагать, что любые данные могут попасть в любое поле. Aaron Wallentine

Ваш Ответ

5   ответов
48

filter_var().

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

echo filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);   
php 5 довольно хороший filter_var (PHP 5> = 5.2.0) Haim Evgi
Мне нравится filter_var, к сожалению, не все настройки хостинга имеют 5.2, но, похоже, это хорошо продуманная функция. artlung
Не все хостинг-версии имеют 5,2, хе-хе, это так, 2009 год. Теперь больше похоже, что они все еще работают с 5,4, они подозрительны. markus
Убедитесь, что вы ничего не передаете функции mail () особенн параметр $ headers) может содержать нефильтрованный текст, особенно\r\n(header): (...); Aaron Wallentine
0

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

4

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

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

12

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

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

$email = filter_var($email, FILTER_SANITIZE_EMAIL);

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

$subject = str_replace(array("\r","\n"),array(" "," "),$subject);
Символы новой строки в темах электронной почты несколько проблематичны. Frank Farmer
Привет, Фрэнк, я отредактировал свой ответ, чтобы отразить твое предложение. Wadih M.
В зависимости от того, как точно построено электронное письмо, в любой заголовок электронной почты можно вставлять символы новой строки, позволяя злоумышленнику добавлять любые новые или заменяющие заголовки электронных писем, которые ему нравятся. В дополнение к этому, вставка целой пустой строки (две строки) позволяет злоумышленнику вставить тело письма по своему выбору, полностью перекрывая сгенерированное письмо. Cheekysoft
4

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() и иным образом ограничивая то, что можно вставить.

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

Похожие вопросы