Был а много из говорящий о проблеме безопасности, связанной с cgi.fix_pathinfo
Параметр PHP, используемый с Nginx (обычно PHP-FPM, быстрый CGI).
В результате в файле конфигурации nginx по умолчанию говорилось:
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
Однако теперь "официальная" вики Nginx утверждает, что PATH_INFO можно обработать правильно, не отключая вышеуказанный параметр PHP. Ну и что?
cgi.fix_pathinfo
делать? (официальный документ просто говорит: "Для получения дополнительной информации о PATH_INFO см. Спецификации CGI")PATH_INFO
и SCRIPT_FILENAME
переменные? Я пытаюсь разобраться в проблеме на каждом этапе. Например, я не понимаю, зачем использовать сокет Unix php-fpm мог избежать Эта проблема.
Я постараюсь ответить на ваши конкретные вопросы, но ваше непонимание того, что такое PATH_INFO, делает сами вопросы немного неправильными.
Первый вопрос должен быть: «Что это за бизнес с информацией о пути?»
Информация о пути указывается после сценария в URI (должна начинаться с косой черты, но заканчивается перед аргументами запроса, которые начинаются с символа ?
). Последний абзац в обзорном разделе Статья в Википедии о CGI резюмирует это красиво. Ниже PATH_INFO
это "/ ЭТО / ЕСТЬ / ПУТЬ / ИНФОРМАЦИЯ":
http://example.com/path/to/script.php/THIS/IS/PATH/INFO?query_args=foo
Ваш следующий вопрос должен был быть таким: «Как PHP определяет, что PATH_INFO
и SCRIPT_FILENAME
являются?"
PATH_INFO
, так что должно было быть PATH_INFO
был наложен на SCRIPT_FILENAME
который, да, во многих случаях сломан. У меня нет достаточно старой версии PHP для тестирования, но я считаю, что она видела SCRIPT_FILENAME
как весь shebang: "/path/to/script.php/THIS/IS/PATH/INFO" в приведенном выше примере (с префиксом docroot, как обычно).PATH_INFO
и SCRIPT_FILENAME
получает только ту часть, которая указывает на запрашиваемый скрипт (конечно, с префиксом docroot).PATH_INFO
, им пришлось добавить параметр конфигурации для новой функции, чтобы люди, выполняющие сценарии, зависящие от старого поведения, могли запускать новые версии PHP. Вот почему для него даже есть переключатель конфигурации. Он должен был быть встроенным (с «опасным» поведением) с самого начала.Но как PHP узнает, что это за часть скрипта и какова его информация о пути? Что, если URI выглядит примерно так:
http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo
SCRIPT_FILENAME
был определен и PATH_INFO
получает остальное.SCRIPT_FILENAME
получает "/foo.jpg" (опять же с префиксом docroot) и PATH_INFO
получает "/nonexistent.php".Теперь должно быть понятно, почему и чем это может быть опасно:
Nginx и Apache могут быть созданы или настроены для предотвращения запросов, использующих эту уловку, и есть множество примеров того, как это сделать, в том числе в user2372674 ответ. Эта статья в блоге хорошо объясняет проблему, но не хватает правильного решения.
Однако лучшее решение - просто убедиться, что PHP-FPM настроен правильно, чтобы он никогда не запускал файл, если он не заканчивается на «.php». Стоит отметить, что в последних версиях PHP-FPM (~ 5.3.9 +?) Это используется по умолчанию, так что эта опасность больше не является большой проблемой.
Если у вас последняя версия PHP-FPM (~ 5.3.9 +?), Вам не нужно ничего делать, так как безопасное поведение, указанное ниже, уже установлено по умолчанию.
В противном случае найдите php-fpm's www.conf
файл (возможно /etc/php-fpm.d/www.conf
, зависит от вашей системы). Убедитесь, что у вас есть:
security.limit_extensions = .php
Опять же, в наши дни это по умолчанию во многих местах.
Обратите внимание, что это не мешает злоумышленнику загрузить файл «.php» в папку загрузки WordPress и выполнить его с использованием той же техники. Вам по-прежнему нужна хорошая безопасность для ваших приложений.
По сути, без этого вы можете загрузить на веб-сервер файл с PHP-кодом, названный как 'foo.jpg'; затем запросите это как http: //domain.tld/foo.jpg/nonexistent.php и стек веб-сервера по ошибке скажет о; это PHP; Мне нужно обработать это, он не сможет найти foo.jpg / nonexistent.php, поэтому он вернется к foo.jpg и обработает foo.jpg как код php. Это опасно, поскольку открывает систему для очень легкого вторжения; любое веб-приложение, позволяющее загружать изображения, например, становится инструментом для загрузки бэкдора.
Относительно использования php-fpm с сокетом unix, чтобы избежать этого; ИМО это не решит проблему.
в Nginx вики в качестве меры безопасности
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
входит в блок локации. В других уроках
try_files $uri =404;
, который должен делать то же самое, но может вызывать проблемы согласно вики Nginx. С помощью этих опций cgi.fix_pathinfo=1
больше не должно быть проблемой. Более подробную информацию можно найти Вот.