Заключение/экранирование переменных в теле письма

Я чувствую себя немного неловко, потому что я генерирую тело письма с помощью PHP без экранирования переменных. В HTML я использую htmlspecialchars() или аналогичные функции для командных строк escapeshellarg(), но для почты? Например что-то вроде этого:

<?php
$usercontent = $_GET['usercontent'];
mail("[email protected]", "My Subject", "My body with $usercontent included");
?>

Что может сделать возможный злоумышленник с помощью сценария, подобного приведенному выше, и как я могу защититься от такой атаки? Или PHP mail() сохраняется и почему?

Обновить

Пожалуйста, обратитесь к примеру:

  • Затрагивается только тело (без заголовков!)
  • Content-Type — текстовый/обычный
  • Некоторые доказательства ответа было бы неплохо
  • MTA — это postfix sendmail с "/usr/sbin/sendmail -t -i"

person Trendfischer    schedule 17.04.2013    source источник
comment
Более рискованное использование почтовой функции связано с ее 4-м параметром, и пока вы не используете ее с пользовательским контентом, я думаю, что вы достаточно безопасны, чтобы использовать ее. В любом случае, я бы рекомендовал использовать стороннюю библиотеку, такую ​​как Swiftmailer swiftmailer.org.   -  person arraintxo    schedule 17.04.2013
comment
Проблемы безопасности, связанные с 4-м параметром, вы также можете посмотреть здесь: stackoverflow.com/questions/4834337/   -  person arraintxo    schedule 17.04.2013
comment
Спасибо за комментарии, о проблемах безопасности с другими параметрами, я прекрасно осведомлен, меня просто интересует тело, например, ввод нескольких писем или что-то в этом роде.   -  person Trendfischer    schedule 17.04.2013


Ответы (4)


Основное тело сообщения электронной почты представляет собой обычный текст. Если вам нужен другой тип, например HTML или составное сообщение, вам необходимо использовать расширение MIME и указать тип соответствующим образом, используя Content-Type (например, text/html для HTML или multipart/… для составного сообщения).

Таким образом, с точки зрения безопасности нет возможности внедрить что-либо вредоносное (по крайней мере, согласно спецификации). Даже символы, отличные от ASCII, должны обрабатываться правильно, несмотря на отсутствие объявления используемой кодировки символов.

Тем не менее, в почтовых клиентах все еще могут быть некоторые недостатки, которые можно использовать таким образом. Но я сомневаюсь в этом.

person Gumbo    schedule 17.04.2013
comment
Имхо, это лучший ответ на данный момент. Content-Type text/html должен быть четким, multipart/... может быть опасным. Хотя мои сомнения еще не удовлетворены. Что с синглом. в строке, например \r\n.\r\n? Может ли это быть опасно? - person Trendfischer; 26.04.2013

Хороший вопрос. Я не верю, что вам нужно экранировать основной текст, но я знаю, что можно добавлять заголовки к почте (например, скрытую копию к тысячам адресов), если вы позволяете пользователю вводить адрес отправителя. Поэтому, если вы помещаете туда переменные, обязательно проверьте наличие новых строк (\n и \r), чтобы убедиться, что не добавлены дополнительные заголовки.

person Rijk    schedule 17.04.2013
comment
Я тоже думал об экранировании новых строк, но переменные не в начале тела. Как с ним добавить дополнительные заголовки. Моя забота больше в понимании проблемы, но спасибо за ответ. - person Trendfischer; 17.04.2013
comment
Так что я думаю, что ты в порядке без побега лично. - person Rijk; 17.04.2013

Думайте о теле письма так: «Совершенно секретная цель миссии неизвестна». Мы можем не знать, какой тип клиента прочитает сообщение, но мы можем догадаться, что мы не хотим, чтобы в нем отображался живой, предоставленный пользователем, неэкранированный HTML. Поскольку многие клиенты читают почту в формате HTML, лучше всего будет htmlentities() ввести текст сообщения электронной почты, предоставленный пользователем.

Метод из моего класса escaper.

<?php
class escaper
{
    public function superHtmlEntities($string)
    {
        return htmlentities($string, ENT_QUOTES | ENT_HTML5, 'UTF-8', true);
    }
}
?>

========================================

Как минимум, рассмотрите что-то подобное и многое другое, когда будете проводить исследование.

<?php
$esc = new Escaper();

$usercontent = $_GET['usercontent'];
mail("[email protected]", "My Subject", $esc->superHtmlEntities("My body with $usercontent included"));
?>
person Anthony Rutledge    schedule 30.04.2015
comment
Экранирование HTML должно быть минимальным. Согласованный. По крайней мере, для типа контента text/html. Но будьте осторожны с кодировкой и убедитесь, что двойное кодирование допустимо. В некоторых библиотеках проверки у вас уже есть закодированный ввод. - person Trendfischer; 04.05.2015

Он не защищен от атаки XSS, потому что если ваша почта содержит HTML, кто-то может внедрить его в почту.

Хорошим поведением является проверка и достоверные данные, которые вы ожидаете получить. Если бы я был тобой, я бы избежал этой строки. Это почти ничего не стоит, и вам не нужно беспокоиться о последствиях его неиспользования.

person Robert    schedule 17.04.2013
comment
Да, это был бы ответ, который я бы дал себе ;-) Но какой тип побега был бы уместным? - person Trendfischer; 17.04.2013
comment
Делать что-то на всякий случай или потому, что это не может навредить, — это не инженерия, а угадывание. Я предпочитаю знать, что на самом деле нужно сделать и почему. - person Nicolas; 21.07.2018