Безопасность файловой системы PHP подчиняется правилам безопасности, которые встроены в бо́льшую часть серверных систем в отношении разрешений для файлов и каталогов. Следование правилам разрешает разработчика управлять тем, какие файлы в файловой системе доступны для чтения. При настройке файлов, доступ на чтение которых есть у мира, соблюдают осторожность, чтобы гарантировать, что файлы безопасны для чтения пользователями с доступом к файловой системе. Поскольку PHP разработали для доступа к файловой системе на уровне пользователя, можно написать PHP-скрипт, который разрешит читать системные файлы наподобие /etc/passwd, изменять Ethernet-соединения, отправлять большие задания на печать и т. д. У этого есть ряд последствий, и поэтому нужно убедиться, что не возникла ошибка с выбором файла, который разработчик читает и в который записывает данные. Рассмотрим следующий скрипт, в котором пользователь указывает, что хотел бы удалить файл из пользовательского домашнего каталога. Это предполагает, что управление файлами регулярно использует веб-интерфейс PHP, поэтому пользователю веб-сервера Apache разрешается удалять файлы в домашних каталогах пользователя. Недостаточная проверка переменных приводит к… ]]> Поскольку имя пользователя и название файла приходят из пользовательской формы, не исключается риск подмены и удаления данных, которые принадлежат другому пользователю, даже если у пользователя не было разрешения на удаление данных. Тогда требуется аутентификация. Посмотрим, что произойдёт, если отправить значения "../etc/" и "passwd". Тогда код будет выглядеть вот так: …атаке на файловую систему ]]> Атаки предотвращают двумя способами. Ограничивают права доступа на двоичный файл веб-пользователя PHP. Проверяют каждую переменную, которую передают пользователи. Вот улучшенный вариант кода: Более безопасная проверка имени файла ]]> Однако даже такая проверка не лишена недостатков. Если система аутентификации разрешает пользователям создавать произвольные логины, и взломщик выбрал логин "../etc/", система снова становится уязвимой. Поэтому предпочитают более строгую проверку: Более строгая проверка имени файла ]]> Набор файлов, за которыми придётся следить разработчику, определяет операционная система, и включает системные файлы устройств /dev/ или COM1, конфигурационные файлы /etc/ и файлы с расширением .ini, хорошо известные области хранения файлов /home/, Мои документы и так далее. Поэтому обычно проще создать политику безопасности, которая запрещает всё, кроме того, что явно разрешили. Нулевые байты и безопасность Поскольку для работы с файловой системой PHP внутренне вызывает функции языка C, он иногда обрабатывает нулевые байты неожиданным образом. Поскольку в C нулевые байты обозначают конец строки, PHP не принимает всю строку с NUL-байтом, а только до позиции перед нулевым байтом. Следующий пример содержит уязвимый код, который показывает проблему: Пример уязвимого скрипта с NUL-байтом ]]> Поэтому каждую испорченную строку, которая участвует в операциях с файловой системой, требуется правильно проверять. Вот улучшенная версия предыдущего примера: Корректная проверка входных данных ]]>