В библиотеке PHPMailer выявлена (https://legalhackers.com/advisories/PHPMailer-Exploit-Remote...) ещё одна критическая уязвимость (CVE-2016-10045), позволяющая выполнить свой код на сервере. Проблема устранена в выпуске PHPMailer 5.2.20 (https://github.com/PHPMailer/PHPMailer/releases). Уязвимость позволяет обойти метод защиты, реализованный для блокирования прошлой уязвимости (https://www.opennet.me/opennews/art.shtml?num=45774), и касается не столько самого PHPMailer, сколько внутренних проблем с функцией mail() и средствами экранирования символов в PHP.Напомним, что уязвимость в PHPMailer позволяла через передачу специально оформленного адреса отправителя, корректного и полностью соответствующего RFC 3696 (https://tools.ietf.org/html/rfc3696), организовать передачу дополнительных аргументов утилите /usb/sbin/sendmail, запускаемой по умолчанию при вызове PHP-функции mail(). Для атаки используется опция "-X", позволяющая записать тело сообщения в переданный в качестве аргумента файл (игнорируется в реализациях утилиты sendmail от проектов Postfix и Exim). Так как формально атака осуществляется через корректный email-адрес, проходящий проверку на предмет соответствия требованиям RFC 3696, при выпуске первого исправления для блокирования уязвимости был добавлен дополнительный вызов escapeshellarg(), производящий экранирование аргументов, передаваемых в функцию mail().
Из-за особенностей PHP данная защита оказалась (https://github.com/PHPMailer/PHPMailer/wiki/About-the-CVE-20...) неэффективной. В частности, для защиты от подстановки дополнительных shell-команд в функции mail() уже применяется экранирование итоговой команды через escapeshellcmd(). Добавленное разработчиками PHPMailer экранирование отдельных аргументов при помощи escapeshellarg() привело к некорректному двойному экранированию спецсимволов, в результате которого на выходе остаётся рабочая команда. Например, попытка отправки по адресу "\"Attacker\\' -Param2 -Param3\"@test.com" приводит к следующей расстановке аргументов при вызове функции mail():
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-f\"Attacker\\\]
Arg no. 4 == [-Param2]
Arg no. 5 == [-Param3"@test.com']Так как выполнение escapeshellcmd(escapeshellarg($address)) ломает всю защиту и штатными средствами устранить уязвимость через экранирование символов оказалось невозможно, разработчики PHPMailer решились на нарушение совместимости с RFC 3696 и в версии PHPMailer 5.2.20 реализовали (https://github.com/PHPMailer/PHPMailer/commit/06aae8b651aa4a...) дополнительную фильтрацию, которая может привести к прекращению обработки некоторых сложных email-адресов.
В ходе разработки исправления был поднят пласт проблем (https://gist.github.com/Zenexer/40d02da5e07f151adeaeeaa11af9...) с функциями escapeshellcmd() и scapeshellarg(), поведение которых отличается для разных платформ и локалей. Кроме mail(), escapeshellcmd() также вызывается в некоторых других PHP-функциях, что мешает применению для них escapeshellarg() для экранирования отдельных аргументов. При включении Safe mode число таких функций расширяется, что создаёт дополнительные скрытые подводные камни при обеспечении безопасности (при включении safe mode защита через escapeshellarg для некоторых функций PHP перестаёт работать). По мнению разработчиков PHPMailer для полноценного устранения проблемы требуется внутренняя переработка функции mail() в PHP, в которой следует вместо строки $additional_parameters подставляемой в выполняемую команду использовать массив отдельных аргументов и обеспечить запуск sendmail напрямую, а не через shell.
Следует отметить, что проблема не ограничивается PHPMailer и, например, вчера обнаружена (https://legalhackers.com/advisories/SwiftMailer-Exploit-Remo...) (CVE-2016-10074) в другой популярной PHP-библиотеке SwiftMailer (http://swiftmailer.org/), которая используется в таких проектах, как Yii2 (https://github.com/yiisoft/yii2-swiftmailer), Laravel (https://laravel.com/docs/5.1/mail) и Symfony (http://symfony.com/doc/current/email.html). Несмотря на то, что разработчики были уведомлены о проблеме ещё 2 декабря, исправление до сих пор не выпущено и последний выпуск SwiftMailer 5.4.5-dev остаётся уязвимым. Метод эксплуатации полностью аналогичен уязвимости в PHPMailer.
$email_from = '"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com';Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fattacker\]
Arg no. 4 == [-oQ/tmp/]
Arg no. 5 == [-X/var/www/cache/phpcode.php]
Arg no. 6 == ["@email.com]
URL: http://openwall.com/lists/oss-security/2016/12/28/4
Новость: http://www.opennet.me/opennews/art.shtml?num=45779
> Из-за особенностей PHPНе из-за "особенностей", а из-за его "дизайна".
[сообщение отредактировано модератором]
>Не из-за "особенностей", а из-за его "дизайна".Это одно и то же.
кэп :-)P.S. Народ совершенно перестал воспринимать сарказм без закадрового смеха или аршинной таблички.
>>Не из-за "особенностей", а из-за его "дизайна".
> Это одно и то же.какие мы грозные. а может все таки кривой RFC?
Плохому программисту RFC мешает.
> Плохому программисту RFC мешает.проблемы в данном случае- возникают из нелепого RFC. Потом у что на практике - то что RFC допускает - не используется в 99,99999% случаев.
Ага знаем мы как ПХП разработчики перекладывают свои болезни на более квалифицированных.
Ну перепишут sendmail как модуль расширения на си, доволен?
Дык давно уже нужно было писать модуль для smtp, а не все подряд звать через exec.Пс: ответственость тут лежит пополам как на пхп, так и на хорошем примере как не надо писать рфс, рфс на все случаи жизни. Думаю нужно от таких рфс избавляться, ярчайщий пример безалаберства проектировщика
> Дык давно уже нужно было писать модуль для smtp, а не все
> подряд звать через exec.Такие модули есть такие и в phpmailer-е, и в swiftmailer-е.
Это не значит, что не надо править уязвимость в модуле, отправляющем через mail().Совсем его выпилить не получится из-за популярности php на shared-хостингах, где и исходящие соединения по 25-му порту, и семейство exec-функций могут быть запрещены - и оставлена только функция mail().
Речь шла о smtp модуле php написанном на С, а так на самом php любой модуль можно написать. И идея была в том, чтобы реализовать его в место поделки вроде функции mail.>>Совсем его выпилить не получится из-за популярности php на shared-хостингах, где и исходящие соединения по 25-му порту, и семейство exec-функций могут быть запрещены - и оставлена только функция mail().
Если исходящие по 25 порту соединения запрещены (а запрещены конкретно пхп или серверу?), то и mail функция работать не будет.
пс: Жутко плохая практика использовать вебсервер в качестве отправщика почты, дык легче с пхп коннектиться к гмейлу и отправлять через него.
Проблемы в данном случае возникают из-за того, что функция mail четвертым и пятым параметром принимает не значение одного аргумента как to, from и msg, которое сама экранирует и подставляет в sendmail, а произвольную строку в качестве _набора_ дополнительных аргументов для sendmail. А вот тут с экранированием возникают некоторые проблемы. Принимала бы вместо строки ассоциативный массив, не было бы проблем.
Нет, проблема возникает из-за идиота, который писал реализацию mail() в PHP.
>Плохому программисту RFC мешает.В мемориз!!
RFC трудились писали, переписывали много - пришли php кодеры и давай всех обгаживать.
> RFC трудились писали, переписывали много - пришли php кодеры и давай всех
> обгаживать.если вы пишите "по стандарту" и в результате получается жопа - то это проблема стандарта а не кодеров.
Если разработчики не могут безопасно реализовать стандарт, то это проблема разработчиков, а не стандарта.
Безопасно реализовать стандарт? Эт как? У вас рфс написано как это делать? Ой простите ваш рфс не знал что некоторые символы разрешенные оказывается являются спец операторами в коммандной оболочке, ой Господи прости меня за кощунства против рфс, во всем виноват пхп и сендмейл который принимает аргументы в коммандной строке, а не интерактивно
Эти символы и в именах файлов, например, разрешены. И ничего, все живы до сих пор. Может, всё-таки, стоит помеьше дёргать шелл, а если дёргать - обеспечивать вменяемую передачу параметров вместо надежды на то, что сам шелл разберётся?
ага слеш разрешён в качестве имени файла
Писали трудились, писаки что ли? Покажите мне код где реализована эта фуллвая спека рфс
> пришли php кодеры и давай всех обгаживать.это НЕ кодеры -- они даже PHP не осилили. кодеры молча кодят и у них всё работает.
вы просто потакаете безответственности и халатности.
RFC подкладывающий "мину замедленного действия" - из -за недодуманности, или "и так сойдет" , или "а давайте и эту хрень воткнем" - плохой RFC.
Владимир Владимирович?
> RFC подкладывающий "мину замедленного действия"При чем тут RFC, когда в PHP банально используют shell для запуска внешних процессов с передачей им списка аргументов в виде строки, вместо того чтобы выполнить exec с раздельной передачей аргументов. Это кривость рук чистой воды и стандарт никоим образом не должен её прикрывать.
> из -за недодуманности, или "и так сойдет" , или "а давайте и эту хрень воткнем" - плохой RFC.
Возможность использование пробелов в недоменной части email ничем не хуже использования пробелов в недоменной части URL, и никто про кривость стандартов там никто и не подумает кричать, ибо привыкли к нормальному экранированию.
https://github.com/php/php-src/commit/8f4050709c833b9d42cd65...
> https://github.com/php/php-src/commit/8f4050709c833b9d42cd65...ext/filter/tests/058.phpt
+'"verî.(),:;<>[]\".VERÎ.\"verî@\ \"verî\".unüsual"@strange.example.com',как бы намекают - какой длб будет использовать такой имейл, а мы всё же его валидируем )))) ппц маразм
кучно пошли
Баг закрыли багом...
Эпично!
это же пхп что от них ожидали
>>Из-за особенностей PHPИ ведь, его такого особенного, ещё кто-то в 2017 будет юзать. Поздравляю ;)
не кто то а большинство.
юзает и будет узать.
и кол-во пользователей будет только увеличиваться.
гдето недавно проскакивала статистика увеличения роста востребовааности PHP.
Да, а вот Гугл Тренды с тобой не согласятся :)
Для веба, будет стандартом де факто - js. Вот увидишь.
Можешь скринить.
Не знаю как где а у нас по Украине в этом году JavaScript отобрал третье место у PHP.
Угу, скорость у жс вменяемая, уникального ie больше нет, и пусть клиент сам себе интерфейс рендерит, жсоном нужные данные отдать и пускай сортирует и фильтрует как нравится - красота.
не ктото а большинство
а в будущем и все перейдут на PHP
Например, все те миллионны форумов, которые используют "phpBB"
следующая новость."ахтунг! в php обнаружена уязвимость в функциях system и exec и т.п. - которая позволяет передавать любые команды на исполнение."
"О сколько нам открытий чудных готовит просвещенья дух!" (с)
т.е. кто-то не фильтрует входящие данные, а виноват пхп? лол
> т.е. кто-то не фильтрует входящие данные, а виноват пхп? лолДа, виноват PHP, так как входящие данные полностью соответствуют RFC.
ну так sql injection тоже проходит в стандарт, давайте теперь не будет проверять данные от пользователей?
Дык, разработчкик PHP Mailer и проверяют данные, но...
Да, виноват похапе. Обезьяны не осилили exec() и продолжают юзать system()
Еще лет 15 назад я на всех своих серваках сделал симлинк /usr/sbin/sendmail на /bin/true, а почту из приложений передаю только по TCP 127.0.0.1:25. Лучшее лекарство от кретинов-программистов.Ах, какой я молодец!
А еще от php кодеров требуется серьезная защита. В php.ini обязательно должно быть:
disable_functions=popen,set_time_limit,passthru,system,exec,proc_open,shell_exec,proc_close,symlink
В контексте этой новости в этот список еще надо добавить mail(). :-)
Я бы добавил disable_functions=* и забиндил пхп процесс на другой ЯзыкП.
угу, а когда тебе надо поставить что-то, что должно отправлять почту - ты сам быстренько разбираешься в паре сот мегабайт чужого странного кода с напластованиями за десяток лет, и быстренько переписываешь в нем PHPMailer или самодельный его заменитель?> а почту из приложений передаю только по TCP 127.0.0.1:25.
msp/lmtp ниасилен или мы даже не слышали про такое? полагаю, бесполезно спрашивать, как твой чудо-код соответствует rfc (соответственно - отреагирует на другой mta на этом 25, а не тот единственный с которым ты его кое-как отладил), как в нем сделана обработка ошибок на всех этапах, в том числе после DATA, кто должен обслуживать этот вот 25й порт с учетом защиты от взлома, спама, взбесившегося скрипта и т д, как это живет при high load учитывая затраты на такую сессиию...
админ локалхоста как есть...
> Лучшее лекарство от кретинов-программистов.
они тебя даже спрашивать не будут - поставят задачу "починить отправку почты из PHPMailer, срок исполнения - пять дней назад, потому что должно было работать сразу". Это когда тебя повысят до админа не локалхоста а чего-то что приносит деньги.
Бвахахаха.У меня наоборот получилось. Когда прогеры начали жаловаться что не вся почта доходит и пых тормозит я им сказал перестать пользовать sendmail, показал в сторону PHPMailer и создал аккаунт для авторизации на почтовом сервере. ЧЯДНТ?
Потом ещё помог сделать базовую очередь отправки сообщений через базу и крон.
> админ локалхоста как есть...
> они тебя даже спрашивать не будут - поставят задачу "починить отправку почты
> из PHPMailer, срок исполнения - пять дней назад, потому что должно
> было работать сразу". Это когда тебя повысят до админа не локалхоста
> а чего-то что приносит деньги.Чегож с тебя так ядовитое дерьмо прет? Совсем неудачник по жизни? Соберись с силами и переломи!
Действительно, не читать же в самом деле админу локалхоста системную почту.
А я нихрена не делал, я подождал когда ко мне прийдут с вопросом "А почему нас постоянно банят за рассылку почты".
Итак, исходя из куска кода:$mail = new PHPMailer();
$email_from = '"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php some"@email.com';
$mail->SetFrom($email_from, 'Client Name');ясно две вещи. Первое какой-то школьник решил, что SetFrom() это мега-метод, который должен принимать на вход не только электронный адрес почты, но также и весь набор параметров к объекту $mail. Хотя нормальные люди делают на каждый входной параметр -- свой метод. И второе, забыв правило "мусор на входе, мусор на выходе" автор сего когда решил обвинять кого угодно, но только не свой код: виноваты те кто писал mail() функцию, те кто писали экранизаторы, вообще все вокруг виноваты, а он, автор расчудесного метода -- нет. Повезло ему, что чужой код оказался не менее бажным, а то бы и дальше искал бы виноватых.