Использование PHP как двоичного CGI это опция установки, когда, по некоторым соображениям, нет желания
интегрировать PHP как модуль в программу-сервер (такую как Apache) или когда PHP
будет использоваться с различными видами CGI-оболочек для создания для
скриптов безопасной среды chroot и setuid. Такая инсталяция обычно заключается в установке исполняемого файла PHP в директорию cgi-bin web-сервера. CERT advisory
CA-96.11
рекомендует не помещать никакие интерпретаторы в директорию cgi-bin. Даже если исполняемый файл PHP
используется как самостоятельный интерпретатор, PHP разработан таким
образом, чтобы предотвратить атаки при таком варианте установки:
Доступ к системным файлам: http://my.host/cgi-bin/php?/etc/passwd
Информация запроса в url после знака вопроса (?) передаётся
интерпретатору как аргументы командной строки CGI-интерфейсом. Обычно
интерпретаторы открывают и выполняют файл, специфицированный как первый аргумент командной строки.
При вызове как исполняемый CGI, PHP не выполняет аргументы командной строки.
Доступ к любому web-документу на сервере: http://my.host/cgi-bin/php/secret/doc.html
Информация пути/path в url после имени PHP-экзешника, /secret/doc.html, используется по
соглашению для специфицирования имени файла, открываемого и исполняемого CGI
-программой. Обычно некоторые директивы конфигурации web-сервера (Apache: Action) используются для перенаправления запросов документа, например, http://my.host/secret/script.php,
интерпретатору PHP. При такой установке web-сервер сначала проверяет права доступа к директории
/secret, а затем создаёт перенаправленный запрос http://my.host/cgi-bin/php/secret/script.php.
К сожалению, если запрос в оригинале задан в этой форме, проверка доступа к файлу
/secret/script.php web-сервером не выполняется, и он делает её только для файла
/cgi-bin/php. Этим способом любой пользователь может получить доступ к /cgi-bin/php
и к любому защищённому документу на web-сервере.
В PHP опция конфигурации времени компиляции --enable-force-cgi-redirect
и директивы времени выполнения doc_root
и user_dir могут использоваться для предотвращения таких нападений, если дерево
документов сервера содержит директории с ограниченным доступом. См. далее рассмотрение различных комбинаций.
Если на вашем сервере нет содержимого, доступ к которому ограничен паролем
или ip, то нет необходимости в применении этих опций конфигурации.
Если ваш web-сервер не разрешает выполнять перенаправление или если он не
имеет способа такого взаимодействия с исполняемым PHP, чтобы запрос был
безопасным, вы можете специфицировать опцию
--enable-force-cgi-redirect
для конфигурирования скрипта. Вы также должны гарантировать, что ваши PHP-скрипты
не основываются на каком-либо другом способе вызова скриптов: ни на прямом
http://my.host/cgi-bin/php/dir/script.php, ни на перенаправлении http://my.host/dir/script.php.
Перенаправление может быть сконфигурировано в Apache через использование директив AddHandler и
Action (см. ниже).
Эта опция времени компиляции предотвращает вызов PHP кем бы то ни было прямо в url, например,
http://my.host/cgi-bin/php/secretdir/script.php.
Вместо этого PHP будет разбирать в этом режиме только в том случае, если пройдено правило перенаправления web-сервера.
Обычно перенаправление в конфигурации Apache выполняется следующими директивами:
Эта опция была проверена только на сервере Apache и основывается на
установке Apache нестандартной переменной окружения CGI REDIRECT_STATUS для перенаправленных запросов.
Если ваш web-сервер не поддерживает способ сообщения того, является ли запрос
перенаправляемым или прямым, вы не можете использовать эту опцию и обязаны
использовать один из других вариантов запуска CGI-версии из указанных здесь.
Включение активного содержимого, такого как скрипты и исполняемые файлы, в директорию документов
web-сервера считается небезопасным. Если они, из-за какой-нибудь ошибки
конфигурации, не исполняются, а выводятся как обычные HTML-документы, это
может привести к потере интеллектуальной собственности или закрытой
информации вроде паролей. Поэтому многие sysadmins предпочитают
устанавливать другую структуру директорий для скриптов, когда они доступны
только для PHP CGI и, следовательно, всегда интерпретируются и не выводятся как текст.
Также, если невозможно гарантировать, что запросы не
перенаправляются, как указано в предыдущем разделе, необходимо установить doc_root
скриптов, которая отличается от web document root.
Вы можете установить корневую директорию скриптов PHP директивой конфигурации
doc_root в файле конфигурации
или можете установить переменную окружения PHP_DOCUMENT_ROOT. Если она установлена, CGI-версия PHP всегда будет конструировать имя
открываемого файла с применением doc_root и информации пути к файлу из запроса, поэтому вы можете быть уверены, что
никакие скрипты не будут исполняться вне этой директории (за исключением user_dir ниже её).
Другая используемая здесь опция - user_dir.
Когда user_dir не установлена/unset, единственное, что контролирует имя открываемого файла, это
doc_root. Открытие url вроде http://my.host/~user/doc.php приводит к открытию не файла под home-директорией пользователя, а файла,
вызываемого ~user/doc.php под doc_root (да, директории с именем, начинающимся с тильды [~]).
Если user_dir установлена для, например, public_php, запрос вроде
http://my.host/~user/doc.php откроет файл doc.php под директорией public_php
ниже home-директории пользователя. Если home пользователя это /home/user, выполняется файл
/home/user/public_php/doc.php.
Расширение user_dir происходит независимо от установки doc_root, поэтому
вы можете контролировать доступ к директории document root и пользовательской директории независимо друг от друга.
Очень надёжной опцией является помещение исполняемого файла разборщика PHP
где-нибудь вне дерева файлов web. В /usr/local/bin, например. Единственным недостатком этой опции является то, что вы теперь
должны помещать строку вроде следующей:
#!/usr/local/bin/php
как первую строку любого файла, содержащего тэги PHP. Вы также должны
сделать файл исполняемым. То есть рассматривать его так же, как любой
другой CGI-скрипт, написанный на Perl или sh или любом другом языке
скриптинга, который использует механизм замены #! оболочки для запуска самого себя.
Чтобы PHP корректно обрабатывал информацию PATH_INFO и PATH_TRANSLATED при такой установке, разборщик РНР должен быть скомпилирован с опцией
конфигурации --enable-discard-path