Изпращане на променливи за PHP FileSystem функции с подаване на формуляр

Опитвам се да намеря сигурен начин да направя следното:

  1. Потребителите въвеждат стойност в html формуляр.
  2. Формулярът е изпратен.
  3. 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);

?>

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