Forum Webscript.Ru

Программирование => PHP => Тема начата: D1g174LM4n14c от 28 Апреля 2004, 14:33:25

Название: Интересная Задача
Отправлено: D1g174LM4n14c от 28 Апреля 2004, 14:33:25
Есть основная директория, в которой разрешено передвигаться пользователям где угодно. Но выше залезть нельзя. Нужно защитить это программным путем.

Скажем, имеем базовый путь

$base = \'/www/home/path/dir/\';


а путь внутри этого каталога приходит к нам вот так

$path = $_GET[\'path\'];


нужно сделать так, чтобы при написании ?path=../
юзер не смог попасть выше базовой директории.
а также надо оставлять юзеру "красивые" пути. То есть, если он пройдется сначала в папку dir1, потом dir2, затем вверх ../ и в папку dir3, снова наверх ../ ТО путь должен быть

$path = \'dir1/\';


а не

$path = \'dir1/dir2/../dir3/../\';


вот в общем-то и все ;)

интересно, кто как решит...
Название: Интересная Задача
Отправлено: Меняздесьдавнонет от 28 Апреля 2004, 15:13:49
удинственное надежное средство - open_base_dir
Название: Интересная Задача
Отправлено: Макс от 28 Апреля 2004, 15:34:00
Если я тебя правильно понял то примерно так.

$base = \'/www/home/path/dir/\'; - базовый путь.
текущий путь
$cur = realpath($base.$_GET[\'dir\']); // проверку данных сам сделаешь
 если strpos($cur, $base) === 0 - то все нормально, в остальных случаях - попытка захода выше базового каталога.


Хотя я в свое время просто запретил точку и использовал лишь пути вида:
/path/to/dir/
Название: Интересная Задача
Отправлено: D1g174LM4n14c от 29 Апреля 2004, 10:49:03
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).\'/\');
Название: Интересная Задача
Отправлено: D1g174LM4n14c от 29 Апреля 2004, 10:51:51
Про "мусор" в путях, чтобы вы не ломали голову, кто не понял - это в данном случае подразумевает пути типа /dir1/dir2/../dir3/. Следовательно, чать пути dir2/../ - лишняя... вот мы и удаляем ненужное :)
Название: Интересная Задача
Отправлено: Меняздесьдавнонет от 29 Апреля 2004, 12:06:58
это все очень длинно.
цикл тут не нужен.
гораздо проще отрезать от пути кусок длиной с разрешенный каталог и сравнить. плюс запретить двоеточия.
Название: Интересная Задача
Отправлено: D1g174LM4n14c от 29 Апреля 2004, 12:40:27
вот цикл как раз для избежания запрета двоеточий =)
хотя если они не столь важны - то, естественно, их лучше запретить =)
мне просто интересно было, как кто подойдет к вышеизложенной задаче ;)
Название: Интересная Задача
Отправлено: Меняздесьдавнонет от 29 Апреля 2004, 12:59:34
ну, я бы подошел одной строчкой

а зачем тебе избегать запрета двоеточий?
Зачем вообще нужны двоеточия?
он что - руками вводить будет?
Название: Интересная Задача
Отправлено: D1g174LM4n14c от 29 Апреля 2004, 13:51:28
запрет для того, чтобы никто не ввел руками path типа ../../
и не вылез за пределы base директории...
Название: Интересная Задача
Отправлено: D1g174LM4n14c от 29 Апреля 2004, 14:22:08
а вот вопросик возник, мож кто сталкивался...
мне нужно написать рег.выр. для нахождения ссылок на директории уровнем выше (../)...
перл-совместимое...
сложность не в нахождении двух точек и слеша, а втом что имена директорий также могут иметь точки в себе, + слеши это опциональный символ... он может стоять после .. или нет (если .. в конце пути)... вот столько всего, блин..
а просто запретить точки в путях - значит запретить какие-то директории (вполне возможно)...
Название: Интересная Задача
Отправлено: Макс от 29 Апреля 2004, 14:25:46
Цитировать
D1g174LM4n14c:
realpath вычисляет результат относительно текущей директории.

если ты ему дашь относительный путь - тогда да.
а если абсолютный - то будет все нормально.
Название: Интересная Задача
Отправлено: D1g174LM4n14c от 29 Апреля 2004, 15:04:41
Макс
ты прав. я проверил... функция не глупая)))
я поначалу думал что она смотрит на пути как на строки, а не как на пути))))))) :D