Как ограничить область выполнения PHP скрипта include?
Здравствуйте. Возникла следующая задача:
Представте себе веб сервер, на котором у каждого «пользователя» есть своя папка, в которую он может загружать свои скрипты. Скрипты — это модули к открытому API проекта, «пользователь» — это программист допущенный взаимодействовать с системой.
Использование скриптов «пользователей» всегда начинается с корневого index.php, который живет в document_root, далее в зависимости от URL собирается цепочка include, в какой то момент подключается кусочек с которым работал «пользователь».
Так как «пользователь» загружает скрипт на чистом PHP — зону видимости таких функций как file(), file_get_contents(), rmdir() необходимо ограничить и свести к работе внутри доверенной ему категории.
Вопрос может показаться глупым и тривеальным, но хочется найти оптимальный способ решения этой задачи.
Буду рад услышать ваши предложения по этому вопросу!
Удваиваю. open_basedir и апач с модулем mpm_itk (каждый сайт/document_root принадлежит отдельному linux-пользователю). Однако, следует помнить, что open_basedir не даёт полноценно использовать некоторые функции (например, curl).
Использование под Nginx накладывает некоторые сложности, хотя я нашел аналогичные реализации.
Но остается вопрос, при использовании через include от действительного корня сервера <document_root>/index.php исполнение функции типа realpath(".") покажет действительный корень или тут папку из которой запускается realpath(".")?
open_basedir не имеет отношения ни к include, ни к document_root
эта директива ничего не подменяет, в том числе поведение realpath.
она просто не дает открывать файлы, расположенные выше указанного каталога.
Kichee, realpath показывает ровно то, для чего он был предназначен. Т.е. realpath.
Если просить его показать '.', т.е. текущую директорию, то он её и покажет. Это ни как не связанно ни с document_root, ни со скриптом в котором написано realpath('.'). Текущая директория это контекстная переменная окружения интерпретатора и она очень легко меняется:
Да, но будет ли include из цепочки инициализированной в <document_root>/index.php определять область видимости внутри этой директории после подключения файла скрипта?
Kichee нет, не будет. choot интерпретатора позволяет лишь отгородить приложение от остальной системы. Внутри самого choot-а разных разработчиков-юзеров приходится разделять на уровне прав доступа к файлам.
alekciy, а надо, чтоб не жили, то есть, чтоб не были доступны (если я правильно понял задачу). Чтобы не было возможности прочитать /etc/ или грохнуть весь /tmp/
Masterme, а системные и не доступны. Просто в choot создаются новые. И в них перетаскивается необходимый для работы минимум (как-то подсистема резолвинга имен).
В контексте задачи лучше чем chroot+грамотные permission на файлы-директории не найти.
Именно, скрипт запускается с index.php, собирается API, его использует «пользователь» в своем скрипте (не хочется загонять программиста в рамки и заставлять его учить какие то дополнительные команлы если можно дать чистый код), НО выше своей директории «пользователь» не должен видеть, читать, удалять и делать что то еще.
Как вариант можно переназначить те функции, которые могут причинить вред и создать для них аналоги с другими путями, но результат пока предствляется сомнительным.
НО выше своей директории «пользователь» не должен видеть, читать, удалять и делать что то еще.
Если код основного движка лежит вне директории пользователя, то для нормальный работы запретить чтение ни как не получится. В случае опасения за исходники скрипты движка стоит кодировать. Остальное, как я уже говорил, решается chroot-от (закрытие основной системы) + правильные права внутри (что бы один юзер не имел доступа к файлам другого). Работать это вполне неплохо может через php-fpm.
Опять же, на сколько я понимаю это даст base_dir если скрипт запускается из этой директории. Будет ли это работать в случае если этот файл подключается через include от корня? Или это и подразумивается реализовывать в сервисной прослойке?
Masterme, Вы не понимаете разницы между запуском всего кода в отдельном пространстве («shared hosting») и желанием запустить include в отдельном пространстве. Где index.php у автора запускается, там и весь остальной подключаемый код будет иметь власть.
EugeneOZ, а, ну, видимо вопрос был так задан и так понят. Я говорил про изоляцию на уровне пользователя ОС. На уровне include, конечно, изоляцию выполнить нельзя.