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