Как стать автором
Обновить

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

полезно, в избранное. Пошел править конфиги.
особенное изображение, которое будет одновременно проходить валидацию размеров GD и исполняться php интерпретатором, будет иметь права на исполнение произвольного кода на сервере с правами php процесса.

А реально такое изображение создать? Ведь в начале каждого img идет бинарный header
НЛО прилетело и опубликовало эту надпись здесь
зачем? Можно просто после конца gif вставить сколько надо и какой хочешь информации, вполне будет валидная картинка
А еще валиднее — EXIF! Очень семантично, валидаторастам на радость!
А что? После тела идет нужный мусор. Я так, в сове время, делал гигабайтные прозрачные гифки 1x1 пиксель ;)
А зачем если не секрет? Просто чтобы подшутить над кем-то?
Гиговый — для сових личных тестов.

Вообще так можно удобно симулировать новый траффик на вполне реальных клиентах
бедные клиенты )
еще никто не жаловался, между прочим. Пока я это делал, я сильно мониторил вебпланету и хабр
если картинка обрабатывается с помощью функций PHP работы с изображениями, то вся EXIF-информация будет удалена
google://rarjpeg
НЛО прилетело и опубликовало эту надпись здесь
перфоманс у вас тоже не возникает, однако
НЛО прилетело и опубликовало эту надпись здесь
MVC хорошая, красивая архитектура. Но, например, тот же Шетухин (вы знаете кто это?) ругался на нее.

Далее, я не понимаю, зачем использовать index.php; php!; для отдачи просто статической картинки?
НЛО прилетело и опубликовало эту надпись здесь
тогда ваш комментарий это просто позерство. Ибо тут обсуждается раздача статики.

Но критика к MVC все так же остается.
НЛО прилетело и опубликовало эту надпись здесь
Я чуть ниже уже высказал мысль, что статику надо отдавать тем, кто это умеет делать хорошо: akamai, amazon cloudfront или любой другой CDN
товарищи с минусами, а расскажите что вам не нравится?
invidia :>
Да хотя бы так: RewriteRule !\.(js|gzip|gz|css|ico|gif|jpe?g|png|zip|txt|xml|htm?l|rar|exe|php|tar|bin)$ index.php [L]
А в папках с графикой запрет на выполнение чего-либо интерпретатором.
htm?l — ошибочка, надо html?
Это не проблема nginx; это проблема тех, кто читает howto и делает по ним, вместо того, что бы прочитать документацию, которая, в основном, на русском!
проблема именно в cgi.fix_pathinfo — fpm тоже не при чём
по-мойму это проблема в недопонимание инструментов, что используют
Проблема как всегда в php. cgi.fix_pathinfo реально сложный инструмент. PATH_INFO изначально появился для SEO-шников, чтобы были красивые урлы (как бы статические, раньше поисковики так любили), если php запускается как CGI и веб сервер не поддерживает rewrite.
Понимаете для какого это года актуально? ;-)
Фича прижилась в php, как и множество других костылей из cgi_main.c.
Также, зачем-то cgi.fix_pathinfo по умолчанию выставили в «1» — спорное решение.
Получается, в случае её использования rewrite происходит непосредственно в php, и это происходит по-умолчанию.
Понятно, что если rewrite помимо этого происходит в веб сервере, то ничего хорошего не получится.
Потом в cgi sapi появилась поддержка fastcgi. это тоже было странно — надо было уже разносить на разные sapi — в cgi и fastcgi не сильно много общего с точки зрения кода. Для эры fastcgi опция уже давно потеряла свой старый смысл и актуальность, но уже не осталось людей, которые имели полную картину происходящего.
Потом fastcgi sapi начали повсеместно использовать с nginx (изначально fastcgi использовался с IIS/zeus и он был сильно специфичнее в использовании).
И вот, наконец, костылики с хрустом начали ломаться обнажая все проблемы что были скрыты все эти годы.
да, забыл добавить.
сама реализация cgi.fix_pathinfo достаточно тормозная — на каждый запрос проверяется каждая компонента пути — не скрипт ли это.
так что её стоит выключать также и по соображениям производительности.
The WWW Common Gateway Interface Version 1.1 8 января 1996 года. PATH_INFO уже есть. Более древних упомининай не нашёл, но уже видно что дела давних дней. Очень давних.
Спасибо! Заэксплуатируем, пока не закрыли.
Что использовать вы хотите? Что закрывать?
Не будут закрывать.
Конструкции вроде /wiki/index.php/Заглавная никто не отменял, да и переход на интерпретатор по *.php тоже.
вы мне скажите, в чем ошибка-то?
Ошибки нет, это не баг, а фича (фичи), поэтому в самом коде nginx по этому поводу, скорее всего, ничего менять не будут. Ошибка если и есть, то в конфигах отдельных конфигураций. А фичи эти вполне часто используемые (те же самые /wiki/index.php/Заглавная).
«Не будут закрывать» == «Пальцем не пошевелят по этому поводу»
Я правильно понимаю, что если за nginx стоит apache, он обработает либо запрос /scripts/1px.gif/test.php либо /scripts/1px.gif и в любом случае не станет выполнять картинку как php-скрипт?
Да. Поведение nginx ровно такое, как его просил автор конфига. Все что кончается на .php выполнять там. Я не пониманию, почему это ошибка.
Как минимум по тому, что просят выполнить .../img/test.gif/.php, а он по факту выполняет .../img/test.gif как PHP.
Покажите мне debug log
Да, это действительн php меняет pathinfo, а не nginx.
тогда топикстартер просто провокатор! Который громко крикнул и убежал в кусты
=)) Ну во-первых, не в кусты, а на обед.
Во-вторых я не писал, что это уязвимость nginx. Читайте внимательно.
Ну и в третьих проблема мне кажеться в том, что оказывается в переменной $fastcgi_script_name. У лайти такого например нету.
А что в ней оказывается в nginx и лайте?
nginx:
/scripts/1px.gif/test.php

lighttpd:
/scripts/1px.gif
проблема в том, что некоторые, используют софт, не думая, что они делают
Всетаки ошибка в том, что nginx по умолчанию делает то, что ему делать не следовало бы, правит pathinfo. Как он вообще догадывается, что нужно проверить существование файла? Там четко написано — если запрос заканчивается на php. Про файлы там вообще ничего нет.
nginx передает этот запрос на fastcgi обработчик. Как обрабатывает его php, nginx как-то не особо волнует
Прошу прощения, проморгал, что cgi.fix_pathinfo пэхэпэшнаю опция. Тогда к nginx никаких претензий.
Топик стартер просто провокатор, это нормально, они почти все такие…
Статику вообще надо держать на отдельном server{}, где нет никаких средств исполнения. И будет счастье.
а лучше на отдельном домене, за который отвечает внешний cdn…

но это, дивный, новый, мир. А мы про суровые, российские будни
Катап решил эпично всех завоевать в этом топике!
Причём не лично, а через, простите, CDN.
Как ни пытался не получается ошибку воспроизвести. Всё время пишет «No input file specified.»
Ах да, у меня используются unix socket'ы
сокеты не влияют
У вас точно cgi.fix_pathinfo установлена в 1?
Она у меня вообще нигде не прописана, даже в php.ini
phpinfo() эту опцию вообще не отображает. Вот конфиг:

location ~ \.php$ {
fastcgi_pass unix:/home/vz/root/201/tmp/php.sock;
fastcgi_index index.php;
fastcgi_param script_FILENAME /home/username/htdocs$fastcgi_script_name;

fastcgi_param QUERY_STRING $query_string;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REQUEST_METHOD $request_method;

fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param script_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
}

Unix socket поднят в виртуальной среде
Т.е. unix:/home/vz/root/201/tmp/php.sock; относится к серверу, а
fastcgi_param script_FILENAME /home/username/htdocs$fastcgi_script_name; уже к виртуальной машине.
А какая версия пхп и с какими ключами собрана?

Судя по php.net/manual/en/ini.core.php:

Available since PHP 4.3.0. PHP_INI_ALL prior to PHP 5.2.1.
5.2.11
Вот ключи:

Configure Command => './configure' '--with-config-file-path=/etc/php5' '--mandir=/usr/share/man' '--enable-memory-limit' '--disable-debug' '--with-regex=php' '--disable-rpath' '--disable-static' '--with-pic' '--with-layout=GNU' '--with-pear=/usr/share/php' '--enable-calendar' '--enable-sysvsem' '--enable-sysvshm' '--enable-sysvmsg' '--enable-trans-sid' '--enable-bcmath' '--with-bz2=/usr/lib' '--enable-ctype' '--without-gdbm' '--with-iconv' '--enable-exif' '--with-gettext' '--enable-mbstring' '--with-pcre-regex=/usr' '--enable-shmop' '--enable-sockets' '--with-libxml-dir=/usr/lib' '--with-zlib' '--with-zlib-dir=/usr/lib' '--with-openssl=/usr' '--enable-soap' '--enable-zip' '--with-mime-magic=' '--with-exec-dir=/usr/lib/php5/libexec' '--with-system-tzdata' '--prefix=/usr' '--without-mm' '--without-sybase-ct' '--without-mssql' '--without-sqlite' '--sysconfdir=/etc/php5' '--with-gd' '--enable-gd-native-ttf' '--with-jpeg-dir=/usr/lib' '--with-png-dir=/usr/lib' '--with-freetype-dir=/usr/lib' '--with-mhash=shared,/usr/lib' '--with-mysql=/usr/lib/mysql/lib' '--enable-shared' '--enable-fastcgi' '--with-fpm' '--with-fpm-conf=/etc/php5/php-fpm.conf' '--with-fpm-log=/var/log/php-fpm.log' '--with-fpm-pid=/var/run/php-fpm.pid' '--with-curl=/usr/lib' '--with-mcrypt=/usr/lib' '--with-libevent=shared'
Ах да, у меня еще PHP 5.2.x
5.2.6 — баг присутствует, только что проверил
Сами проверьте:
Уже пофиксили, видимо
Сработал адрес вида site/file.gif%00.php

Ушел патчить
Помогло вот это:

location ~ \00 {
deny all;
}
А теперь
location ~ \01 {
deny all;
}
И так далее.
%01 не обозначает конец строки и никак не влияет на уязвимость
Бугога =) Капитан очевидность. Баге этой сто лет в обед.
Да, знаю, я специально указал Announcement date. Просто сёдня в очередной раз нашёл её на нескольких сайтах, решил написать на хабре, может админы заметят.
Еще раз спасибо, кэп. Но багу далеко не первый год. Это «стандартная» уязвимость у админского нубья. С Apache mod_cgi та же фигня.
НЛО прилетело и опубликовало эту надпись здесь
нафиг пользователям загружать картинки если их нельзя посмотреть?
НЛО прилетело и опубликовало эту надпись здесь
ещё есть аналогичный «нюанс» с путями вида httр://........./image.gif%00.php
у меня выдаёт 400 Bad request, что в принципе логично
А вот это у меня сработало
А вот у меня нет — почему?
Можно просто проверить существует ли файл и вернуть, например, 404 Not Found:

location ~ \.php$ {
try_files $uri =404;
include «fastcgi_params»;
fastcgi_pass ...;
fastcgi_param ...;
}
вообще тут нужно с умом подойти. в nginx есть куча способов от этой вещи отмазаться, но если у вас генерятся картинки (sic!) или что-то другое на лету, тут надо думать
Я везде использую такую конструкцию, проверяющую наличие файла:

location ~ \.php$ {
	if ( -f $request_filename ) {
		fastcgi_pass		unix:/tmp/php-fpm.sock;
	}
	fastcgi_index			index.php;
	fastcgi_param			script_FILENAME /nginx/html$fastcgi_script_name;
	include				fastcgi_params;
}
где-то в рассылке nginx пробегало, что конструкции с if лучше избегать.
Да не, можно использовать. Говорите всем что катаб вам позволяет.

Только стоит понимать что делает if и почему у вас будут сегфолы и никто править не будет ;)
Ого, я вижу, что кусок моего конфига ушел в пост. Мелочь, а приятно :))
Что для меня всегда было загадкой, так это возможность upload'ить картинки в каталог "/scripts/".
НЛО прилетело и опубликовало эту надпись здесь
Спасибо! Закрыл. Правда говоря трюк с php.ini почему-то не прошел. Сделал через конфиги nginx'а.
хм… топик обновлен.
if ( $fastcgi_script_name ~ \..*\/.*php ) {
return 403;
}
а чем этого мало?
все. понял :))
А мой патч, который исправляет все эти проблемы сразу, так и не приняли… :/
Сорри, отправилось раньше.

Желто.
На нормальном конфиге php НИКОГДА не должен обрабатываться в пути, куда может заливать юзер.
Это реализуется, как было описано выше, редиректом всей динамики на index.php, как вариант — наличие php-скриптов в отдельном от статики месте или location ^~ для статики.

НЛО прилетело и опубликовало эту надпись здесь
А ЧПУ будет работать?
БОльшая часть известных ЧПУ реализована через htaccess, тут уже не nginx
Имею в виду битриксы, джумлы, велоЦМС etc.
Я просто забыл о существовании apache, поэтому и спросил.
У меня в конфиге насколько я помню эта строчка ведет не на 404, а на /bitrix/urlrewrite.php
Тем более тема о связке nginx + php-cgi
Во всех HowTo по настройке связки nginx с php-fpm / php-cgi есть похожие строчки:
НЛО прилетело и опубликовало эту надпись здесь
С ужасом сейчас обнаружил, что в дефолтном php-правиле у cherokee таки есть эта уязвимость.
«Починил», добавив к выполнению *.php файлов условие File Exists :) Теперь нормально.
Немного апну тему :)
Не работает на свежей связке nginx + php-fpm, так как в конфиге php-fpm есть строчка
;security.limit_extensions = .php .php3 .php4 .php5
Которая не даст выполнить другие файлы.
На всякий случай уточню, что не работает не из-за наличия вышеупомянутой строчки (";" в начале означает, что строка закомментирована), а из-за применения самого подхода с белым списком в конфиге — по умолчанию разрешено только расширение .php, и чтобы снова стать уязвимым к описанному в топике, нужно ручками добавить новое расширение и перезапустить php5-fpm :)

Как это сейчас выглядит для конфига в php 5.4.23
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; exectute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории