Я хочу убедиться, что путь к файлу, заданный через строку запроса, не выходит за пределы нужного подкаталога. Прямо сейчас я проверяю, что:
- Путь не начинается с "
/
", чтобы пользователь не мог указать абсолютный путь.
- Путь не содержит "
..
", чтобы пользователь не мог указать путь, который находится за пределами нужного подкаталога.
- Путь не содержит "
:
", чтобы предотвратить использование URL (т. Е. "http://
", "ftp://
" и т. Д.). Если я когда-либо выполню этот сценарий на сервере Windows (маловероятно), это также предотвратит абсолютные пути, начинающиеся со спецификатора диска (т. Е. "C:\
"). Примечание: я знаю, что двоеточие является допустимым символом в именах файлов Unix, но я никогда не буду использовать его в имени файла.
- Путь не начинается с "
\
". На случай, если я передумаю работать на сервере Windows, это не позволит указать сетевые пути Windows (т. Е. "\\someserver\someshare
"). Опять же, я знаю, что обратная косая черта является действительным символом имени файла Unix, но я также не буду использовать его в именах файлов.
Достаточно ли этих проверок?
Фон
У меня есть PHP-скрипт, который принимает (через строку запроса) путь к примеру исходного файла, который будет показан пользователю. Поэтому я могу дать им ссылку типа "view_sample.php?path=accounting_app/report_view.php
" или "view_sample.php?path=ajax_demo/get_info.js
".
Сценарий выглядит в основном так:
$path = $_GET['path'];
if(path_is_valid($path) && is_file("sample/$path"))
{
header('Content-Type: text/plain');
readfile("sample/$path");
}
Меня беспокоит, что злоумышленник увидит URL и попытается сделать что-то вроде "view_sample.php?path=../../database/connection_info.php
" и получить доступ к файлу, который не в каталоге "sample".
Достаточно ли четырех указанных мной проверок (которые будут реализованы в функции path_is_valid()
) достаточно, чтобы заблокировать злоумышленника? (Кроме того, я думаю, что проверки 1, 3 и 4 в основном не имеют значения, так как я предпочитаю относительный путь, но если я этого не сделаю, проверок будет достаточно?)