Комментарии 76
Оригинал первой части текста тут: http://www.netangels.ru/support/articles…
Google RFC не писан, как оказалось. При разделении заголовков символом CRLF (что соответствует RFC 822) следующая строка считается уже телом письма, т.к. Google и CR и LF воспринимает как перевод строки. В итоге при прохождении письма через smtp.gmail.com получаем кашу из заголовков, текста и b64. Поэтому приходится использовать LF специально для GMail =)
«Q-кодирование» правильно называется «quoted printable», теперь можете найти эту функцию в PHP, она есть в модуле IMAP, но можно написать и свою, на php.net в комментариях есть несложный пример.
Оп-па, спасибо! Я как раз думал, как передать нормально заголовок письма из формы на сайте.
Спасибо, очень познавательно..
Чтобы грамотно отправлять почту из скриптов надо взять готовый отлаженный класс и не изобретать велосипед.
По-моему понимать, как оно работает - лишним быть не может. :)
Нифига ты не понимаешь в изоюретении велосипедов.
Меня реально не устраивает ни один скрипт. при том что я вообще не программист, я написал свой по мотивам нескольких. Задал проверку полей, выучился маленько регэкспам для распознавания теоретически верного и очень сложного мыла, и то не идеально (сейчас переделываю). Готовые и отлаженные пригодны для безошибочной отправки конкретного типа сообщения. А мне нужно, чтобы совсем разные по формату сообщения проходили.
Меня реально не устраивает ни один скрипт. при том что я вообще не программист, я написал свой по мотивам нескольких. Задал проверку полей, выучился маленько регэкспам для распознавания теоретически верного и очень сложного мыла, и то не идеально (сейчас переделываю). Готовые и отлаженные пригодны для безошибочной отправки конкретного типа сообщения. А мне нужно, чтобы совсем разные по формату сообщения проходили.
Готовый скрипт - это прекрасно, но все таки полезно знать то, с чем имеешь дело. Меньше подводных камней будет.
В этом проявляется разница между веб-мастером и программистом.
Изумительно, абзацем выше за те же слова только в другой форме был заминусован хьюиТрикс :)
В примерах используется прямая вставка из $_POST, но не описано что такое mail-инъекция и способы борьбы с ней. ИМХО, это гораздо важнее для "грамотного отправления почты", чем указание субтипов.
задача стояла другая. совсем. :)
Расскажите лучше про mail-инекцию.
Всё дело в том, что переменная $_POST["subject"] никак не фильтруется, из-за этого можно сформировать свой заголовок и тело письма.
Это я понимаю. То потенциально есть возможность выполнить свой код на сервере?
На сервере нельзя, но можно в _POST['subject'] отправить строку "subject\ncc:много, много email-адресов". В итоге при простой подстановке данной строки в заголовки, получим:
В итоге от имени вашего сервера на все эти адреса будут отосланы сообщения с содержимым, которое обычно так же вводит клиент в браузере.
Subject: subject
cc: [много, много адресов]
В итоге от имени вашего сервера на все эти адреса будут отосланы сообщения с содержимым, которое обычно так же вводит клиент в браузере.
И будет спам... Спасибо за разъяснения.
Ну уж, ну уж!
base64_encode закодирует в буквы и перевод строки, так что ничего подобного не случится.
base64_encode закодирует в буквы и перевод строки, так что ничего подобного не случится.
Сам собой закодирует?
Не понял вопроса. Конечно, сам собой.
base64_encode("subject\ncc:много, много email-адресов")
даёт в результате строку
c3ViamVjdApjYzrNzs/Hzywgzc7Px88gZW1haWwtwcTSxdPP1w==
В результате подстановки данной строки в заголовки ровным счётом ничего плохого не случится.
base64_encode("subject\ncc:много, много email-адресов")
даёт в результате строку
c3ViamVjdApjYzrNzs/Hzywgzc7Px88gZW1haWwtwcTSxdPP1w==
В результате подстановки данной строки в заголовки ровным счётом ничего плохого не случится.
Так откуда этот самый base64_encode возьмется сам собой?
А он собственно есть в примерах, про которые Вы говорили:
"В примерах используется прямая вставка из $_POST, но не описано что такое mail-инъекция и способы борьбы с ней. ИМХО, это гораздо важнее для "грамотного отправления почты", чем указание субтипов." :)
"В примерах используется прямая вставка из $_POST, но не описано что такое mail-инъекция и способы борьбы с ней. ИМХО, это гораздо важнее для "грамотного отправления почты", чем указание субтипов." :)
??? Я не знаю, что вы подразумеваете по "сам собой", но он есть в тот самом примере, на который вы сослались.
$subject = "=?windows-1251?b?" . base64_encode($_POST["subject"]) . "?=";
$subject = "=?windows-1251?b?" . base64_encode($_POST["subject"]) . "?=";
«Version 5.2.2
03-May-2007
Fixed a header injection via Subject and To parameters to the mail() function (MOPB-34 by Stefan Esser) (Ilia)»
03-May-2007
Fixed a header injection via Subject and To parameters to the mail() function (MOPB-34 by Stefan Esser) (Ilia)»
А тебя не смутило то что нет открывающего
А тебя не смутило отсутствие откывающего оператора <?
или например отсутствие конфига какого-нибудь? который по-любому там где-нибудь в начале скрипта по-любому подключается, или например название файла
или редактора в котором писался текст или ещё чего-нибудь абсолютно неуместного ? Нет ?
Этот код ДЛЯ НАГЛЯДНОСТИ !!!
Извини конечно, но ИМХО зря такие комментарии делаются, просто ни к чему.
P.S. Ramm, я не на твоём месте, но будья на твоём месте я бы не распылясля
отвечать на подобные вещи, не напряшайся, эти каменты
на мой взгляд - просто желание вставить свои 5 копеек. А за статью большое спасибо.
или например отсутствие конфига какого-нибудь? который по-любому там где-нибудь в начале скрипта по-любому подключается, или например название файла
или редактора в котором писался текст или ещё чего-нибудь абсолютно неуместного ? Нет ?
Этот код ДЛЯ НАГЛЯДНОСТИ !!!
Извини конечно, но ИМХО зря такие комментарии делаются, просто ни к чему.
P.S. Ramm, я не на твоём месте, но будья на твоём месте я бы не распылясля
отвечать на подобные вещи, не напряшайся, эти каменты
на мой взгляд - просто желание вставить свои 5 копеек. А за статью большое спасибо.
Остынь, гражданин, и не нервничай.
Потом подавляющее число читателей берет подобный код "для наглядности" и вставляет не думая.
И говорил я не именно про какой-то код, а про то, что отслеживание подобных вещей напрямую относится к вопросу о том "как грамотно отправлять почту из скриптов".
Потом подавляющее число читателей берет подобный код "для наглядности" и вставляет не думая.
И говорил я не именно про какой-то код, а про то, что отслеживание подобных вещей напрямую относится к вопросу о том "как грамотно отправлять почту из скриптов".
Если кто-то не думая вставит такой код к себе, то это его проблемы, я лишь хотел сказать что не зачем цепляться за такие моменты, потому как цель другая у него (куска кода) другая. А если вот так цепляться к автору за такие моменты, то можно тысячу раз уйти в сторону от темы основной темы.
Понимание RFC лишним не бывает, однако, решать тривиальные задачи самостоятельно - не стоит. Есть масса готовых библиотек: PHPMailer, ezComponents::Mail, PEAR::Mail_Mime.
+ сюда же Zend::Mail
Баги в библиотеках исправлять всё равно придётся.
иногда проще изобрести велосипед:) особенно с такими хостингами как Агава и РБК, сейчас с ними к счастью не общаюсь, но не забуду как в письма через Ж вставлялись теги антиспама. Агава исправила за неделю, РБК так и не исправила(последний опыт общения июль этого года)
О, да, тут я полностью согласен! Взять хотя бы ручное закачивание PEAR-библиотек, отсутствие необходимых модулей PHP или невозможность собрать собственный интерпретатор. Хостинги иногда творят совершенно невообразимые вещи. Я для себя выбрал мастерхост - пусть, иногда поддержка там как в мультике - "выглядят они не слишком привлекательно, но ничего". :) Зато, ещё ни разу не упирался в нерешаемые проблемы с хостингом.
Согласен с мнением общественности...
Метод кодирования заголовков пожалуй стоит запомнить, но остальным пусть занимаются библиотеки... Уж если надо письма с вложениями отправлять - вникать в это просто некогда.
Метод кодирования заголовков пожалуй стоит запомнить, но остальным пусть занимаются библиотеки... Уж если надо письма с вложениями отправлять - вникать в это просто некогда.
Хотя в студенческие времена - это было так увлекательно... )
С мнением общественности не согласен. Если так думать, то кто будет писать и поддерживать библиотеки? Хотя, кто-то правильно выше заметил, что это и есть разница между веб-мастером и программистом. Я так понимаю, на Хабре все-таки большинство веб мастеров.
Немного не в кассу, но мне кажется, многие библиотеки уже давно пишутся с оглядкой на другие аналогичные библиотеки, потому как сервисы, для которых эти библиотеки пишутся сами по себе реализовываются с отклонениями от RFC. И первично бывает уже не знание RFC, а знание нюансов реализаций этого самого RFC в том или ином случае. :)
Взять тот же самый ezComponents::Mail. По-умолчанию и, вроде как, по стандарту, разделитель заголовков - "\r\n". В реальности, нужно использовать "\n", иначе половина почтовых служб отображает письмо как Б-г на душу положит. :)
Взять тот же самый ezComponents::Mail. По-умолчанию и, вроде как, по стандарту, разделитель заголовков - "\r\n". В реальности, нужно использовать "\n", иначе половина почтовых служб отображает письмо как Б-г на душу положит. :)
какая реальность, если клиент не понимает \r\n (правильно по RFC), то это упущение его разработчиков. И если ты собираешь письмо вручную, будь добр делать по RFC.
Ну а если ты разработчик клиента для чтения почты, то тебе нужно учитывать тот факт, что разделение может быть и \r\n и \n и собственно просто \r (как у Маков кажись старых).
Ну а если ты разработчик клиента для чтения почты, то тебе нужно учитывать тот факт, что разделение может быть и \r\n и \n и собственно просто \r (как у Маков кажись старых).
Если я делаю сайт, мне в некоторых случаях важно не соответствие стандарту, а работоспособность. В частности, gmail плохо ведёт себя с '\r\n' - показывает лишние переносы строк. По моему опыту (точнее, результатам проверки в популярных программах-клиентах, и на почтовых сервисах большинства подписчиков на http://www.mixfight.ru), '\n' понимается в большем числе случаев, чем '\r\n', так что я буду использовать это разделение вопреки стандарту, пусть это и не лучшее решение.
10x a lot! Для меня хабра уже превращается в справочник по вебу, и вы только что внесли отличный вклад в его наполнение! :))
спасибо. есть несколько вещей, на поиск которых пришлось бы потратить некоторое время. теперь они есть тут.
Пропущен весьма существенный заголовок:
MIME-Version: 1.0
Без него получающая система не будет обязана интерпретировать ни квотед-принтабл, ни указание на чарсет в заголовках. Кроме того, не провентилированным остался вопрос, как именно мы отправляем почту:
1) вызываем /usr/sbin/sendmail,
2) пытаемтся послать на порт 25/tcp на локальный хост,
3) пытаемтся послать на смартхост, где-то описанный,
4) или может (о ужас), самостоятельно ищем MXы.
Во всех случаях технология может несколько разниться, особенно в части формирования заголовков. В частности, в первом лучше передавать их в команде:
$stat = mail (null, 'тема сообщения', 'тело сообщения',
"To: Адресат addressee@email.address>\r\nFrom: Отправитель sender@email.address>", '-t');
(русские слова там для примера, должно быть или ASCII, или майм-кодирование)
Кроме того, статья предлагает использовать однобайтную кодировку CP-1251, что никак не может быть признано хорошей рекомендаций в нынешних реалиях. В качестве примера тот же хабр, как люди мучаются с вводом символов за пределами этой кодировки.
MIME-Version: 1.0
Без него получающая система не будет обязана интерпретировать ни квотед-принтабл, ни указание на чарсет в заголовках. Кроме того, не провентилированным остался вопрос, как именно мы отправляем почту:
1) вызываем /usr/sbin/sendmail,
2) пытаемтся послать на порт 25/tcp на локальный хост,
3) пытаемтся послать на смартхост, где-то описанный,
4) или может (о ужас), самостоятельно ищем MXы.
Во всех случаях технология может несколько разниться, особенно в части формирования заголовков. В частности, в первом лучше передавать их в команде:
$stat = mail (null, 'тема сообщения', 'тело сообщения',
"To: Адресат addressee@email.address>\r\nFrom: Отправитель sender@email.address>", '-t');
(русские слова там для примера, должно быть или ASCII, или майм-кодирование)
Кроме того, статья предлагает использовать однобайтную кодировку CP-1251, что никак не может быть признано хорошей рекомендаций в нынешних реалиях. В качестве примера тот же хабр, как люди мучаются с вводом символов за пределами этой кодировки.
По-моему, это вещи уровня параметра boundary, о котором я написал.
Т.е. это такие вещи, проблемы с которыми приведут к очевидным проблемам еще на этапе тестирования - разработчик заметит и займется.
Описанные мной проблемы могут скрываться очень долго. Особенно если и программист и тот, кото принимает его работу пользуются чем-то вроде The Bat!, который при отображении писем вообще на RFC с высокой колокольни плюет.
И будут проблемы типа "а чо, у меня-то работает все как надо, это у вас кривой клиент, ставьте The Bat!"
Т.е. это такие вещи, проблемы с которыми приведут к очевидным проблемам еще на этапе тестирования - разработчик заметит и займется.
Описанные мной проблемы могут скрываться очень долго. Особенно если и программист и тот, кото принимает его работу пользуются чем-то вроде The Bat!, который при отображении писем вообще на RFC с высокой колокольни плюет.
И будут проблемы типа "а чо, у меня-то работает все как надо, это у вас кривой клиент, ставьте The Bat!"
Ох, проблемы приведут к проблемам.
Мда, кажется я заговариваюсь. Извините. :)
Мда, кажется я заговариваюсь. Извините. :)
аха, заговариваетесь ;)
а за статью большое спасибо
только не хватает принципов формирования частей письма, назначения boundary и т.п.
не должны содержаться символы, не присутствующие в ASCII таблице - латинские буквы, цифры, знаки пунктуации и псевдографики.кажется, вы здесь что-то напутали )
а за статью большое спасибо
только не хватает принципов формирования частей письма, назначения boundary и т.п.
есть также полезная функция mb_encode_mimeheader (http://php.net/manual/en/function.mb-encode-mimeheader.php) которая выполняет пример из статьи одним махом.
по поводу готовых классов: порой задача очень проста (форма контактов на простеньком сайте) и внедрять туда код размером в 10kb нет желания, достаточно просто функции mail(), но и ее надо использовать грамотно, в чем эта статья и помогает
кстати, если отправлять письмо с Content-type: text/html, желательно не забывать про теги , многие фильтры дают за их отсутствие много спам-баллов
по поводу готовых классов: порой задача очень проста (форма контактов на простеньком сайте) и внедрять туда код размером в 10kb нет желания, достаточно просто функции mail(), но и ее надо использовать грамотно, в чем эта статья и помогает
кстати, если отправлять письмо с Content-type: text/html, желательно не забывать про теги , многие фильтры дают за их отсутствие много спам-баллов
Pear/Mail
http://pear.php.net/package/Mail_Mime
http://pear.php.net/package/Mail_Mime
Вы не поверите, но на этот пакет даже ссылка в тексте есть. Зачем Ваш комментарий?
Случайно не туда нажал на отправить а потом забыл дописать. Хотел дополнительно прислать ссылку на дискуссию с моим участием на сайте pear http://pear.php.net/bugs/bug.php?id=30 а проблемах и способах устранения некоторых недочетов в pear/mail
Кстати, если вы пишете от 2045 и далее, желательно написать что это далее заканчивается 2049 :-)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Как грамотно отправлять почту из скриптов (в частности — на PHP)