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