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

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

Ну и вопросы такие:

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

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


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


person Juan Ignacio    schedule 09.11.2011    source источник
comment
Я могу думать об атаках XSS и, может быть, инъекциях заголовков; поэтому очистите свой html (если вы используете этот тип MIME) и убедитесь, что никто не вводит пользовательский код в заголовки ваших писем.   -  person Damien Pirsy    schedule 10.11.2011
comment
Удалите все непечатаемые символы, используйте кодировку US-ASCII. Также удалите символы \r\n. Преобразование табуляции в пробелы.   -  person hakre    schedule 10.11.2011
comment
Отличный вопрос. Мне только жаль, что я не исчерпал свой жалкий лимит голосов на сегодня.   -  person Lightness Races in Orbit    schedule 10.11.2011
comment
Вы говорите, что у вас есть довольно хорошая идея, так почему бы не показать, что вы придумали, чтобы никому не пришлось повторять вашу работу? ;-)   -  person CodeCaster    schedule 10.11.2011
comment
Заметьте, я сказал «идея», а не «я знаю», и это потому, что я имел в виду именно это. У меня есть идеи, я знаю кое-что, но я не профессионал в этом вопросе, поэтому я подумал, что, возможно, совместный список вещей, о которых нужно позаботиться, будет лучше, чем мои предположения. И я задаю этот вопрос, потому что я много гуглил и нашел много материала по этому вопросу, но не нашел исчерпывающей статьи (ничего даже близко не похожего на определенное руководство по безопасной электронной почте php, что было бы неплохо)   -  person Juan Ignacio    schedule 10.11.2011


Ответы (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);
}
person Laith Shadeed    schedule 09.11.2011
comment
Я думаю, что есть еще одна атака, которая позволяет добавлять несколько сообщений после каждого тела. Однако это не так хорошо задокументировано. Suhosin защищает PHP от внедрения заголовков почты. - person hakre; 10.11.2011
comment
Кажется очень интересной библиотекой. Это первый раз, когда я вижу это. Но как мы можем убедиться, что это не оказывает побочного эффекта на сам PHP, я проверил его исходный код, который он воспроизводит с внутренними компонентами PHP. Используется ли он на некоторых крупных надежных веб-сайтах? - person Laith Shadeed; 10.11.2011
comment
Ну, по умолчанию он поставляется с PHP в Debian;) - person hakre; 10.11.2011
comment
Читатели, столкнувшиеся с этим, могут заметить, что PEAR_Mail больше не обновляется часто. Последний релиз был больше года назад, а предыдущий — 6 лет назад. Zend_Mail (теперь под брендом zend-mail), похоже, все еще активно поддерживается, его документы теперь здесь: zendframework.github.io/zend-mail/intro Другими популярными и поддерживаемыми в настоящее время библиотеками являются PHPMailer и Swift Mailer. - person IMSoP; 06.03.2017