Защита файлового менеджера PHP от его пользователей - PullRequest
1 голос
/ 03 марта 2009

Привет всем, я разрабатываю веб-сайт для обмена фотографиями с использованием CodeIgniter PHP Framework . Идея состоит в том, что люди могут загружать свои фотографии, управлять ими (через своего рода файловый браузер, который позволяет им создавать подпапки, перетаскивать файлы и т. Д.) И редактировать их (некоторые основные вещи, такие как изменение размера, поворот и обрезка для начала, и позже я добавлю некоторые дополнительные функции).

Я уже внедрил стороннее решение для аутентификации для CI ( Redux Authentication 2 Beta ), и сейчас я интегрирую файловый менеджер JS / PHP ( AjaxExplorer ), но проблема в том, что бэкэнд PHP для управления файлами (перемещение, копирование и т. д.) слишком доверяет пользовательскому вводу из вызовов ajax. Например, он делает такие вещи (для ясности упрощено):

move_uploaded_file($_FILES['upload']['tmp_name'], $root.$username.$_POST['destination_dir']);

Как видите, существуют очевидные проблемы с безопасностью, так как он слепо принимает любой путь, который выберет пользователь! Я уже вижу, что кто-то отправляет что-то вроде "../AnotherUser/" в качестве значения $ _POST ['destination_dir'].

Мой вопрос: Каков наилучший способ «песочницы» пользователя, чтобы он мог только управлять своими собственными данными? Должен ли я просто проверять + фильтровать входные данные, надеясь перехватить каждую попытку вторжения? Существуют ли какие-либо библиотеки / пакеты, предназначенные для решения этой конкретной проблемы?

Я думаю, что эта проблема должна быть каким-то образом решена в любом (достаточно зрелом) проекте, который дает своим пользователям возможность управлять своими файлами через веб-браузер, поэтому я ожидал найти некоторые четкие рекомендации по этому вопросу (так как есть много о SQL-инъекциях, XSS, CSRF и т. д.), но, думаю, я не использую правильные ключевые слова.

Ответы [ 3 ]

6 голосов
/ 04 марта 2009

Каков наилучший способ «песочницы» пользователя, чтобы он мог управлять только своими собственными данными?

Разрешить любые имена файлов / каталогов, которые хочет пользователь, но просто не использовать их в файловой системе на стороне сервера. Вместо этого запишите имена путей в базу данных с первичным ключом и используйте первичный ключ в качестве имени файла, такого как «34256.dat», в плоском каталоге хранения (или даже в качестве BLOB-объекта в базе данных, если хотите). Затем выполните загрузку с помощью сценария загрузки или перезаписи URL-адреса, чтобы желаемое имя файла появилось в URL-адресе.

Санитарная обработка входящих имен файлов hard . Обнаружение "..." - это только начало. Слишком длинные имена файлов; слишком короткие имена файлов; комбинации ведущих и конечных точек; комбинации ведущих и конечных пробелов; разные разделители каталогов разных платформ; символы, недопустимые на некоторых платформах; управляющие персонажи; Символы Unicode и специфичные для среды способы их решения; АДА; имена файлов (‘.htaccess’) или расширения (ph .php ’,‘ .cgi ’), которые могут быть« особенными »для вашего веб-сервера; Зарезервированные имена файлов Windows ...

Вы можете потратить всю жизнь, выискивая забавные маленькие причуды правил filepath на различных платформах, или можете просто забыть об этом и использовать базу данных.

0 голосов
/ 03 марта 2009

Нет библиотеки, о которой я знаю.
Однако в вашем конкретном примере удалите все (назад) косые черты и точки из строки, а затем добавьте косую черту в конец, чтобы пользователь не мог менять папки.

$destdir = str_replace(array('.', '/', '\\'), '', $_POST['destination_dir']); 
$destdir .= "/";
0 голосов
/ 03 марта 2009

Я не уверен, как выглядит ваш destination_dir, но я подумал о том, чтобы назначить ключи каталогов, а затем получить каталог на основе этого ключа. Например:

//$_POST['destination_dir'] = '4hg43h5g453j45b3';
*_query('SELECT dir FROM destinations WHERE key = ? LIMIT 1'); //etc.

Однако вы должны предварительно определить ключи перед рукой. Другой альтернативой может быть противоположность: введите md5 / sha1 и используйте его в качестве destination_dir, затем сохраните этот ключ в базе данных со связанной меткой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...