Отправка переменных для функций PHP FileSystem с отправкой формы
Я пытаюсь найти безопасный способ сделать следующее:
- Пользователи вводят значение в HTML-форму.
- Форма отправлена.
- PHP использует переданное значение в качестве аргумента для функции "scandir".
Моя теория состоит в том, чтобы включить логику в скрипт php, который запрещает абсолютные пути и требует, чтобы имя каталога включало определенное значение.
Меня беспокоит то, что хакер может использовать мою форму, чтобы представить свою ценность и получить доступ к конфиденциальным файлам.
Это для плагина JQuery. Я не хочу, чтобы пользователям приходилось изменять файл PHP.
Как взломать код ниже?
<?php
$foo = $_POST["some_directory"];
//validate $foo
//make sure path to directory is relative
$foo_url_test = parse_url($foo);
if (isset($foo_url_test['scheme']) || isset($foo_url_test['host'])) {
$foo = NULL;
}
//make sure the directory name contains 'bar123'
$foo_name_test = preg_split('_[\\\\/]_', $foo);
$foo_name_test = end($foo_name_test);
$foo_name_test = strpos($foo_name_test,'bar123');
if ($foo_name_test === false) {
$foo = NULL;
}
//make sure the path does not contain '..'
$foo_dot_dot_test = strpos($foo,'..');
if ($foo_dot_dot_test == TRUE || $foo_dot_dot_test === 0) {
$foo = NULL;
}
//get files
$files_array = scandir($foo);
?>
3 ответа
Возможно, вы захотите посмотреть на realpath ().
$foo = realpath($foo);
if (substr($foo, 0, 8) != '/my/path') {
return false;
}
...или что-то типа того.
Вам, вероятно, нужно более подробно рассказать о цели этого скрипта и о том, почему он хочет читать произвольные каталоги. Без этих знаний трудно комментировать безопасность этого кода, кроме того, чтобы указать, что это чрезвычайно опасная вещь, без четких ограничений на доступные каталоги.
Я, например, никогда не установил бы скрипт PHP на мой сервер, который позволял бы удаленному злоумышленнику указать каталог для чтения или даже узнать, существуют ли какие-либо конкретные файлы или каталоги.
Существует веский аргумент для ТРЕБОВАНИЯ пользователя отредактировать файл конфигурации, прочитанный php, который позволяет владельцу сервера занести в белый список набор каталогов, которые могут быть открыты этим сценарием.
Обновление после ответа от ОП
Проблема, с которой вы столкнулись, заключается в том, что все запросы "ajax" выполняются непосредственно из браузера. Это означает, что любые данные, которые веб-сервер устанавливает на html-странице, которая делает запрос ajax, могут быть перезаписаны злоумышленником. Ваш ajax-запрос может быть сделан любым пользователем в любое время с любым параметром, если вы не гарантируете его, чтобы сделать иначе.
Как только ваши данные покидают ваш сервер, вы больше не можете доверять этому. Лучший способ сделать это безопасным - это держать белый список разрешенных каталогов на стороне сервера. Если вы получаете запрос на каталог, которого нет в списке разрешенных (или, возможно, нет в подкаталоге, находящемся под чем-то в списке разрешенных), вы отклоняете запрос и выдает стандартный ответ об ошибке.
Ваше имя каталога может содержать ..
элементы, чтобы они могли смотреть за пределы текущего рабочего каталога, которым вы хотите их ограничить. Однако они по-прежнему смогут просматривать только каталоги, названные так, как вы намереваетесь.
FWIW, используя parse_url()
анализировать, является ли имя каталога относительным, действительно странно. Почему бы тебе просто не поискать $foo[0] == '/'
?
(Конечно, это предполагает соглашение о пути Unix, но ваш код уже делает это.)