Escape-строка для использования в mail()

Конечно, при использовании MySQL вы используете mysqli_real_escape_string() и убедитесь, что тип полученного ввода соответствует ожидаемому (строка, число и т. д.), и вы можете быть уверены, что можете использовать его как вход для mysqli_query() довольно безопасно... верно?

Ну, вопросы:

  • Каков наилучший способ избежать строки, которая будет использоваться в mail()?
  • Если получателем электронной почты будет адрес электронной почты, введенный в текстовом поле, с какими вещами я должен быть осторожен, чтобы избежать инъекций или эксплойтов?

У меня есть довольно хорошая идея, как это сделать, но я изучаю лучшие практики по этому вопросу, чтобы узнать, что я что-то упустил или есть лучший способ.


РЕДАКТИРОВАТЬ: Идея этого вопроса не в том, чтобы получить ответ, а в том, чтобы составить исчерпывающий совместный список всех вещей, о которых нужно позаботиться при работе с электронной почтой с помощью PHP.

1 ответ

Решение

Идея внедрения электронной почты заключается в том, что злоумышленник вставляет перевод строки (LF) в заголовки сообщений электронной почты, поэтому он добавляет столько заголовков, сколько хочет. Удаление этих перевода строки защитит вас от этой атаки. Для получения подробной информации проверьте http://www.phpsecure.info/v2/article/MailHeadersInject.en.php

Лучшая практика - полагаться на хорошо написанный, часто обновляемый и широко используемый код. Для этого я бы предложил использовать PEAR_MAIL ИЛИ Zend_Mail

Если вы не хотите загружать эти модули или вам нужно, чтобы все было очень просто. Вы можете извлечь функциональность фильтрации из этих модулей. Хотя я рекомендую использовать их и часто обновлять библиотеку, чтобы в случае появления новой атаки вам просто нужно было обновить библиотеку (Pear или Zend), и все готово.

Это функция, которая очищает заголовки в пакете Pear Mail:

function _sanitizeHeaders(&$headers)
{
    foreach ($headers as $key => $value) {
        $headers[$key] =
            preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
                         null, $value);
    }
}

Zend_Mail использует другой фильтр для электронной почты, имени и других полей:

function _filterEmail($email)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
                  '"'  => '',
                  ','  => '',
                  '<'  => '',
                  '>'  => '',
    );

    return strtr($email, $rule);
}

function _filterName($name)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
                  '"'  => "'",
                  '<'  => '[',
                  '>'  => ']',
    );

    return trim(strtr($name, $rule));
}

function _filterOther($data)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
    );

    return strtr($data, $rule);
}
Другие вопросы по тегам