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

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

Хорошая закладка от АНБ. Или суперкорявые руки разработчиков. На выбор.
К сожалению, оценить корявость ваших рук не выходит — не обнаружил ссылки на ваш github-профиль.
Это же тролль, не надо его кормить :)
Степень корявости моих рук не затрагивает вопросы безопасности данных других пользователей.
Достаточно редкая уязвимость, чтобы быть закладкой.
Заплатка 18 строк. Кто короче?
Но ведь суть патча в одной строке.
А вам нужно на 30 растянуть?
Что бы новые появились :)))
придётся добавить jQuery :-)
уязвимость, мягко говоря, потенциальная…

php код в upload файлах научились фиксить ещё на заре phpbb, не говоря уже о trim, и других условиях сервера

да и сам браузер разве позволит залить файл с пробелом? это тебе не
echo "lala" > "here "
(про браузер погорячился, можно же и консольный запрос отправить)
Потенциальность тут скорее в другом: никто в здравом уме не называет файлы тем именем, которое передал пользователь. Работать с таким сложно и бессмысленно. Ну и даже если так, вроде бы при типовой конфигурации вида location /uploads/ префикс отрезать тоже не получится, а если в /uploads/ обрабатываются *.php — эта, с позволения, конфигурация была дырява уже давно.
Вообще, если честно, мне пришлось поправить конфигурацию, чтобы эксплуатировать эту уязвимость.
Применительно к php5-fpm ИМХО ключевым является то, что в _дефолтной_ настройке файл с пробелом на конце просто не выполнится. Если админ эту настройку поменял, то он уже «сам себе злобная буратина».

К сожалению, у меня нет экспертизы в python, perl и других языках, исполняющихся как fcgi, но подозреваю, что там есть аналогичная настройка.

Далее, далеко не во всех конфигурациях PATH_TRANSLATED (SCRIPT_FILENAME) зависит от параметров реквеста. Например, на всех наших проектах точка входа одна на сервер, поэтому этот параметр задан константой.

В общем, уязвимость хоть и вполне реальная, но достаточно специфичная, поэтому массовых взломов скорее всего не будет.
К сожалению, у меня нет экспертизы в python, perl и других языках, исполняющихся как fcgi, но подозреваю, что там есть аналогичная настройка.
Там в принципе нет такой пробелемы, как нет и исполняемых файлов в document root веб-сервера.
Все же, это от конфигурации зависит. У меня php-файлов в document root тоже нет. Другое дело, что шаред-хостинги и популярные cms приучили людей к плохому, и то, что в мире python исключение, в php, к сожалению, скорее правило.
Там в принципе нет такой пробелемы, как нет и исполняемых файлов в document root веб-сервера.

Получается, здесь советуют неправильную конфигурацию wiki.nginx.org/DjangoFastCGI?
Нет, там все правильно. Статика — в /media, а исполнимые файлы — в /, вторая локация никак не сможет перекрыть первую.
В принципе, мы пишем подобные конфиги.
Например, вот мой любимый, за авторством klestoff

	server {
		fastcgi_next_upstream off;
		listen		*:80;
		server_name	example.com;

		access_log	/var/log/nginx/example.com.access_log extended;
		error_log	/var/log/nginx/example.com.error_log warn;

		root /var/www/example.com/src/htdocs;
		
		location / {
			access_log /var/log/nginx/example.fpm.access_log extended;
			
			include /etc/nginx/fastcgi_params;
			fastcgi_param PATH_TRANSLATED /var/www/example.com/src/htdocs/index.php;
			fastcgi_param SCRIPT_FILENAME /var/www/example.com/src/htdocs/index.php;
			fastcgi_pass  cbs5;
		}

                location /css/ { }
                location /js/  { }
                location /img/ { }
	}

а /uploads добавляется подобным же образом, верно?
Ну так же как /css/. Эта локация является «более частной» в сравнении с /, поэтому конфигурация унаследуется с уровня server.
PATH_TRANSLATED при наличии SCRIPT_FILENAME не нужен: если SCRIPT_FILENAME присутствует, PATH_TRANSLATED игнорируется.

И уж совсем не в тему, но все же — еще советую в конфигурации PHP ставить cgi.fix_pathinfo=0, иначе (при дефолтном 1) там выполняется жуткий код, унаследованный от старого CGI sapi, написанный для совместимости с древними кривыми серверами, который может запросто с десяток stat()-ов дернуть на каждый вызов.
В отличии от php, на fastcgi_pass слушает само приложение — настоящий честный FastCGI демон, а не запускатель .py файлов на каждый запрос. Этот демон, за редким исключением, не интерпретирует и не умеет интерпретировать произвольного кода, произвольных .py файлов по запросу.

У php же это болезнь доставшаяся ему исторически. Исторически .php — шаблонизатор, и им остается по сей день. Полноценный FastCGI (не в смысле протокола, а в смысле идеологии) на нем можно получить только используя не сильно популярные штуки, вроде phpdaemon и подобных.
fastcgi_param SCRIPT_FILENAME /path/to/application/main.php — и получаем примерно то же самое на PHP.

Да, fastcgi accept-цикл находится внутри FPM SAPI, и приложение заново инициализируется на каждый запрос, но это нельзя назвать однозначным недостатком или преимуществом.
Будет ли фикс добавлен в выложенные архивы версий 1.2-1.4?
в какие архивы? на сайте можно скачать 1.4.4, в тот же squeeze обновление уже пришло
запросив файл как "/file \0.php".

Извините, я чего-то не понимаю.

Это же пробел не на конце, а перед точкой. Конец имени — это после второй буквы p.

Соответственно, glob *.php — срабатывает для этого файла, \.php$ — срабатывает. В чём проблема-то? В том, что если загрузить файл php, то будут проблемы? Ну так не давайте загружать файлы php.

И второе. Как вообще в линуксе можно получить файл с именем, содержащим \0 в середине имени? Этот символ в именах файлов же не допускается.
Почитайте примеры внимательно.
В GET вы передаете "/hole \0.php", регулярка, задающая локацию для fcgi срабатывает, и $script_filename принимает значение "hole "
\0 в имени файла не нужна.

В чём проблема-то? В том, что если загрузить файл php, то будут проблемы?

Проблема в том, что злоумышленник _потенциально_ может исполнить любой файл с пробелом на конце как скрипт.
А, спасибо. Дошло.
Как раз $fastcgi_script_name принимает честное значение, с \0. Проблема возникает в тот момент, когда php-fpm запихивает это в системный вызов open(), который, как и большинство ему подобных, работает с null-терминированными строками.
Вообще, если посмотреть на проблему массовых взломов, то перед злоумышленниками встаёт 3 проблемы:

1) Обойти функцию trim() в CMS.
2) Обойти resize картинки в случае загрузки исполняемого кода как изображения.
3) Обойти переименовывание файлов после аплоадинга.

Если 2 и 3 пункт ещё могут как-то решиться, например, этим способом, и нахождением CMS, где загруженные файлы не переименовываются. То обход первого пункта — наиболее трудный.

А в совокупности все 3 проблемы очень сильно ограничивают злоумышленников в своих массовых взломах. Так что по сути, бояться сильно то и нечего.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории