Отправка переменных для функций файловой системы PHP с отправкой формы

Я пытаюсь найти безопасный способ сделать следующее:

  1. Пользователи вводят значение в html-форму.
  2. Форма отправлена.
  3. PHP использует представленное значение в качестве аргумента для функции «сканировать».

Моя теория заключается в том, чтобы включить логику в скрипт 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);

?>

person edt    schedule 01.07.2009    source источник
comment
Кстати, всегда проверяйте возврат strpos() на «false», используя «===»!   -  person deceze♦    schedule 01.07.2009


Ответы (3)


Вы можете посмотреть на realpath().

$foo = realpath($foo);
if (substr($foo, 0, 8) != '/my/path') {
    return false;
}

...или что-то вроде того.

person deceze♦    schedule 01.07.2009

Вероятно, вам нужно более подробно остановиться на цели этого скрипта и почему он хочет читать произвольные каталоги. Без этих знаний трудно комментировать безопасность этого кода, кроме как указать, что это чрезвычайно опасно, без четких ограничений на доступные каталоги.

Я, например, никогда бы не установил на свой сервер PHP-скрипт, который позволяет удаленному злоумышленнику указать каталог для чтения или даже узнать, существуют ли определенные файлы или каталоги.

Существует веский аргумент в пользу того, чтобы ТРЕБУЕТСЯ, чтобы пользователь отредактировал файл конфигурации, прочитанный php, что позволяет владельцу сервера внести в белый список набор каталогов, которые разрешено открывать этому сценарию.

Обновление после ответа от OP

Проблема, с которой вы столкнулись, заключается в том, что все запросы «ajax» выполняются непосредственно браузером и из него. Это означает, что любые данные, которые веб-сервер устанавливает на html-странице, выполняющей запрос ajax, могут быть перезаписаны злоумышленником. Ваш запрос ajax может быть сделан кем угодно в любое время с любым параметром, если вы не защитите его, чтобы сделать иначе.

Как только ваши данные покидают ваш сервер, вы больше не можете им доверять. Лучший способ сделать это безопасным — создать белый список разрешенных каталогов на стороне сервера. Если вы получаете запрос на каталог, которого нет в списке разрешенных (или, возможно, не в подкаталоге под чем-то в списке разрешенных), вы отклоняете запрос и даете стандартный ответ об ошибке.

person Cheekysoft    schedule 01.07.2009
comment
Сценарий представляет собой подключаемый модуль JQuery, который добавляет отображение изображения на веб-страницу. Веб-мастер добавляет имя каталога, в котором находятся изображения, в оператор плагина: ‹script›$('#some_div').the_plugin({image_location: 'some_directory'})‹/script› Мне нужен безопасный способ используйте эту настройку, чтобы несколько веб-страниц могли использовать плагин с разными изображениями и каталогами, но все используют один и тот же документ php. - person edt; 01.07.2009
comment
Кстати: плагин передает имя каталога через AJAX в php-скрипт, который возвращает html, включая теги изображений и т. д. Затем плагин добавляет этот html на веб-страницу. - person edt; 01.07.2009

Имя вашего каталога может содержать элементы .., чтобы они могли выходить за пределы текущего рабочего каталога, которым вы хотите их ограничить. Однако они по-прежнему смогут просматривать только каталоги, названные так, как вы намереваетесь.

FWIW, использование parse_url() для анализа того, является ли имя каталога относительным, действительно странно. Почему бы тебе просто не поискать $foo[0] == '/'?

(Конечно, это предполагает соглашение о пути Unix, но ваш код уже делает это.)

person chaos    schedule 01.07.2009
comment
Спасибо за предложение. Я изменил пример кода в своем вопросе, чтобы он работал с типами пути ms-dos или unix. Вы видите какие-либо проблемы? - person edt; 01.07.2009