Как стать автором
Поиск
Написать публикацию
Обновить

Комментарии 76

Google RFC не писан, как оказалось. При разделении заголовков символом CRLF (что соответствует RFC 822) следующая строка считается уже телом письма, т.к. Google и CR и LF воспринимает как перевод строки. В итоге при прохождении письма через smtp.gmail.com получаем кашу из заголовков, текста и b64. Поэтому приходится использовать LF специально для GMail =)
Наверное вы используете postfix и просто не умеете с ним работать. У google всё в порядке.
Нет, используется ssmtp и у остальных серверов все в порядке. Можете поставить эксперимент и отправить почту вручную через smtp.gmail.com:465
«Q-кодирование» правильно называется «quoted printable», теперь можете найти эту функцию в PHP, она есть в модуле IMAP, но можно написать и свою, на php.net в комментариях есть несложный пример.
Оп-па, спасибо! Я как раз думал, как передать нормально заголовок письма из формы на сайте.
Спасибо, очень познавательно..
Ну за что? За что? Я был так рад прочитать это.. В обозримом будущем собирался писать такой скрипт.. А вы... Эх вы..:(
Фигней не занимайтесь. PHPMailer
По-моему понимать, как оно работает - лишним быть не может. :)
Заипал спам на хабре. RTFM
Вы, собственно, о чем?
Спасибо за минусы, подрачил :D
О! спасибо, использую, радуюсь!
Чтобы грамотно отправлять почту из скриптов надо взять готовый отлаженный класс и не изобретать велосипед.
По-моему понимать, как оно работает - лишним быть не может. :)
Нифига ты не понимаешь в изоюретении велосипедов.
Меня реально не устраивает ни один скрипт. при том что я вообще не программист, я написал свой по мотивам нескольких. Задал проверку полей, выучился маленько регэкспам для распознавания теоретически верного и очень сложного мыла, и то не идеально (сейчас переделываю). Готовые и отлаженные пригодны для безошибочной отправки конкретного типа сообщения. А мне нужно, чтобы совсем разные по формату сообщения проходили.
Готовый скрипт - это прекрасно, но все таки полезно знать то, с чем имеешь дело. Меньше подводных камней будет.
В этом проявляется разница между веб-мастером и программистом.
Изумительно, абзацем выше за те же слова только в другой форме был заминусован хьюиТрикс :)
а что изумительного? он сам выбрал эту "другую" форму, вот и "напросился"
Посмотрите внимательно, "за те же слова" он получил +5
В примерах используется прямая вставка из $_POST, но не описано что такое mail-инъекция и способы борьбы с ней. ИМХО, это гораздо важнее для "грамотного отправления почты", чем указание субтипов.
задача стояла другая. совсем. :)
тогда стоило указывать просто переменные $subject, $to, etc.
в показательных примерах не стоит делать привязки )
Расскажите лучше про mail-инекцию.
Всё дело в том, что переменная $_POST["subject"] никак не фильтруется, из-за этого можно сформировать свой заголовок и тело письма.
Это я понимаю. То потенциально есть возможность выполнить свой код на сервере?
На сервере нельзя, но можно в _POST['subject'] отправить строку "subject\ncc:много, много email-адресов". В итоге при простой подстановке данной строки в заголовки, получим:

Subject: subject
cc: [много, много адресов]

В итоге от имени вашего сервера на все эти адреса будут отосланы сообщения с содержимым, которое обычно так же вводит клиент в браузере.
И будет спам... Спасибо за разъяснения.
Ну уж, ну уж!
base64_encode закодирует в буквы и перевод строки, так что ничего подобного не случится.
Сам собой закодирует?
Не понял вопроса. Конечно, сам собой.
base64_encode("subject\ncc:много, много email-адресов")
даёт в результате строку
c3ViamVjdApjYzrNzs/Hzywgzc7Px88gZW1haWwtwcTSxdPP1w==
В результате подстановки данной строки в заголовки ровным счётом ничего плохого не случится.
Так откуда этот самый base64_encode возьмется сам собой?
А он собственно есть в примерах, про которые Вы говорили:
"В примерах используется прямая вставка из $_POST, но не описано что такое mail-инъекция и способы борьбы с ней. ИМХО, это гораздо важнее для "грамотного отправления почты", чем указание субтипов." :)
Во-первых, повторюсь, я про это говорил не только для этих примерах, а вообще, о том, что неплохо бы сказать о такой проблеме.
Во-вторых, $_POST['email'] вставляется в примере напрямую.
??? Я не знаю, что вы подразумеваете по "сам собой", но он есть в тот самом примере, на который вы сослались.
$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)»
А тебя не смутило то что нет открывающего
А тебя не смутило отсутствие откывающего оператора <?
или например отсутствие конфига какого-нибудь? который по-любому там где-нибудь в начале скрипта по-любому подключается, или например название файла
или редактора в котором писался текст или ещё чего-нибудь абсолютно неуместного ? Нет ?
Этот код ДЛЯ НАГЛЯДНОСТИ !!!
Извини конечно, но ИМХО зря такие комментарии делаются, просто ни к чему.
P.S. Ramm, я не на твоём месте, но будья на твоём месте я бы не распылясля
отвечать на подобные вещи, не напряшайся, эти каменты
на мой взгляд - просто желание вставить свои 5 копеек. А за статью большое спасибо.
Остынь, гражданин, и не нервничай.
Потом подавляющее число читателей берет подобный код "для наглядности" и вставляет не думая.
И говорил я не именно про какой-то код, а про то, что отслеживание подобных вещей напрямую относится к вопросу о том "как грамотно отправлять почту из скриптов".
Если кто-то не думая вставит такой код к себе, то это его проблемы, я лишь хотел сказать что не зачем цепляться за такие моменты, потому как цель другая у него (куска кода) другая. А если вот так цепляться к автору за такие моменты, то можно тысячу раз уйти в сторону от темы основной темы.
Успокойтесь, уже запинаетесь.
К чему вас вдруг понесло? Я написал один комментарий, а с вашей помощью развели уже на страницу.
Понимание RFC лишним не бывает, однако, решать тривиальные задачи самостоятельно - не стоит. Есть масса готовых библиотек: PHPMailer, ezComponents::Mail, PEAR::Mail_Mime.
+ сюда же Zend::Mail
Баги в библиотеках исправлять всё равно придётся.
иногда проще изобрести велосипед:) особенно с такими хостингами как Агава и РБК, сейчас с ними к счастью не общаюсь, но не забуду как в письма через Ж вставлялись теги антиспама. Агава исправила за неделю, РБК так и не исправила(последний опыт общения июль этого года)
О, да, тут я полностью согласен! Взять хотя бы ручное закачивание PEAR-библиотек, отсутствие необходимых модулей PHP или невозможность собрать собственный интерпретатор. Хостинги иногда творят совершенно невообразимые вещи. Я для себя выбрал мастерхост - пусть, иногда поддержка там как в мультике - "выглядят они не слишком привлекательно, но ничего". :) Зато, ещё ни разу не упирался в нерешаемые проблемы с хостингом.
Согласен с мнением общественности...
Метод кодирования заголовков пожалуй стоит запомнить, но остальным пусть занимаются библиотеки... Уж если надо письма с вложениями отправлять - вникать в это просто некогда.
Хотя в студенческие времена - это было так увлекательно... )
С мнением общественности не согласен. Если так думать, то кто будет писать и поддерживать библиотеки? Хотя, кто-то правильно выше заметил, что это и есть разница между веб-мастером и программистом. Я так понимаю, на Хабре все-таки большинство веб мастеров.
Немного не в кассу, но мне кажется, многие библиотеки уже давно пишутся с оглядкой на другие аналогичные библиотеки, потому как сервисы, для которых эти библиотеки пишутся сами по себе реализовываются с отклонениями от RFC. И первично бывает уже не знание RFC, а знание нюансов реализаций этого самого RFC в том или ином случае. :)

Взять тот же самый ezComponents::Mail. По-умолчанию и, вроде как, по стандарту, разделитель заголовков - "\r\n". В реальности, нужно использовать "\n", иначе половина почтовых служб отображает письмо как Б-г на душу положит. :)
какая реальность, если клиент не понимает \r\n (правильно по RFC), то это упущение его разработчиков. И если ты собираешь письмо вручную, будь добр делать по RFC.
Ну а если ты разработчик клиента для чтения почты, то тебе нужно учитывать тот факт, что разделение может быть и \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, что никак не может быть признано хорошей рекомендаций в нынешних реалиях. В качестве примера тот же хабр, как люди мучаются с вводом символов за пределами этой кодировки.
По-моему, это вещи уровня параметра boundary, о котором я написал.
Т.е. это такие вещи, проблемы с которыми приведут к очевидным проблемам еще на этапе тестирования - разработчик заметит и займется.

Описанные мной проблемы могут скрываться очень долго. Особенно если и программист и тот, кото принимает его работу пользуются чем-то вроде The Bat!, который при отображении писем вообще на RFC с высокой колокольни плюет.

И будут проблемы типа "а чо, у меня-то работает все как надо, это у вас кривой клиент, ставьте The Bat!"
Ох, проблемы приведут к проблемам.
Мда, кажется я заговариваюсь. Извините. :)
аха, заговариваетесь ;)
не должны содержаться символы, не присутствующие в ASCII таблице - латинские буквы, цифры, знаки пунктуации и псевдографики.
кажется, вы здесь что-то напутали )

а за статью большое спасибо
только не хватает принципов формирования частей письма, назначения boundary и т.п.
На самом деле, статья писалась для работы, когда выяснилось, что подавляющее большинство наших программистов правильно сформировать письмо не могут.

Про boundary они знают.

Впрочем, возможно Вы правы - в следующий раз буду дописывать в подобные материалы базовые вещи.
есть также полезная функция mb_encode_mimeheader (http://php.net/manual/en/function.mb-encode-mimeheader.php) которая выполняет пример из статьи одним махом.

по поводу готовых классов: порой задача очень проста (форма контактов на простеньком сайте) и внедрять туда код размером в 10kb нет желания, достаточно просто функции mail(), но и ее надо использовать грамотно, в чем эта статья и помогает

кстати, если отправлять письмо с Content-type: text/html, желательно не забывать про теги , многие фильтры дают за их отсутствие много спам-баллов
Вы, вероятно, имели в виду html, title и body? :)
именно, даже не заметил что фильтр их потер, хоть досточно html, body
Pear/Mail
http://pear.php.net/package/Mail_Mime
Вы не поверите, но на этот пакет даже ссылка в тексте есть. Зачем Ваш комментарий?
Случайно не туда нажал на отправить а потом забыл дописать. Хотел дополнительно прислать ссылку на дискуссию с моим участием на сайте pear http://pear.php.net/bugs/bug.php?id=30 а проблемах и способах устранения некоторых недочетов в pear/mail
Кстати, если вы пишете от 2045 и далее, желательно написать что это далее заканчивается 2049 :-)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации