Forum Webscript.Ru
Программирование => PHP => Тема начата: D1g174LM4n14c от 28 Апреля 2004, 14:33:25
-
Есть основная директория, в которой разрешено передвигаться пользователям где угодно. Но выше залезть нельзя. Нужно защитить это программным путем.
Скажем, имеем базовый путь
$base = \'/www/home/path/dir/\';
а путь внутри этого каталога приходит к нам вот так
$path = $_GET[\'path\'];
нужно сделать так, чтобы при написании ?path=../
юзер не смог попасть выше базовой директории.
а также надо оставлять юзеру "красивые" пути. То есть, если он пройдется сначала в папку dir1, потом dir2, затем вверх ../ и в папку dir3, снова наверх ../ ТО путь должен быть
$path = \'dir1/\';
а не
$path = \'dir1/dir2/../dir3/../\';
вот в общем-то и все ;)
интересно, кто как решит...
-
удинственное надежное средство - open_base_dir
-
Если я тебя правильно понял то примерно так.
$base = \'/www/home/path/dir/\'; - базовый путь.
текущий путь
$cur = realpath($base.$_GET[\'dir\']); // проверку данных сам сделаешь
если strpos($cur, $base) === 0 - то все нормально, в остальных случаях - попытка захода выше базового каталога.
Хотя я в свое время просто запретил точку и использовал лишь пути вида:
/path/to/dir/
-
RomikChef
open_base_dir - это что? =))
я такого не нашел))
Макс
1. Это не подходит. realpath вычисляет результат относительно текущей директории.
2. Тоже вариант. Надо подумать... Может и пожертвую точками))
-----
А вот мой вариант:
// разбиваем $_GET[\'path\'] на составляющие
// и удаляем пустые и \'.\' элементы
$path = array_diff(explode(\'/\', $_GET[\'path\']), array(\'\', \'.\'));
$i = 0; // "смещение" от базовой дирекории. положительное - вниз. отрицательное - вверх
foreach ($path as $k => $v)
{
if ($v == \'..\')
{
--$i;
// если вышли за пределы базовой директории...
if ($i < 0) { $path = \'\'; break; }
// иначе удаляем два элемента (.. и тот что перед ним).
// тем самым чистим от мусора пути
else { unset($path[$k], $path[$k-1]); }
}
else ++$i;
}
$path = (empty($path) ? \'\' : implode(\'/\', $path).\'/\');
-
Про "мусор" в путях, чтобы вы не ломали голову, кто не понял - это в данном случае подразумевает пути типа /dir1/dir2/../dir3/. Следовательно, чать пути dir2/../ - лишняя... вот мы и удаляем ненужное :)
-
это все очень длинно.
цикл тут не нужен.
гораздо проще отрезать от пути кусок длиной с разрешенный каталог и сравнить. плюс запретить двоеточия.
-
вот цикл как раз для избежания запрета двоеточий =)
хотя если они не столь важны - то, естественно, их лучше запретить =)
мне просто интересно было, как кто подойдет к вышеизложенной задаче ;)
-
ну, я бы подошел одной строчкой
а зачем тебе избегать запрета двоеточий?
Зачем вообще нужны двоеточия?
он что - руками вводить будет?
-
запрет для того, чтобы никто не ввел руками path типа ../../
и не вылез за пределы base директории...
-
а вот вопросик возник, мож кто сталкивался...
мне нужно написать рег.выр. для нахождения ссылок на директории уровнем выше (../)...
перл-совместимое...
сложность не в нахождении двух точек и слеша, а втом что имена директорий также могут иметь точки в себе, + слеши это опциональный символ... он может стоять после .. или нет (если .. в конце пути)... вот столько всего, блин..
а просто запретить точки в путях - значит запретить какие-то директории (вполне возможно)...
-
D1g174LM4n14c:
realpath вычисляет результат относительно текущей директории.
если ты ему дашь относительный путь - тогда да.
а если абсолютный - то будет все нормально.
-
Макс
ты прав. я проверил... функция не глупая)))
я поначалу думал что она смотрит на пути как на строки, а не как на пути))))))) :D