2014-01-08 4 views
0

Я получил чужой код для системы, в которой отображаются папки с фотографиями в них в вашем браузере.PHP realpath не работает, чтобы предотвратить обход каталога

Например, это возможно гиперссылка на сайте:

gallery.php?action=view&folder=Cars 

На данный момент, вы можете заменить «Тачки» с ../../../../../, который будет с радостью отображать корневую папку Linux. К счастью, веб-сайт в настоящий момент отключен.

Я попытался использовать realpath, чтобы исправить это. Вот что у меня есть до сих пор:

case 'view' : 
$name = realpath(dirname(__FILE__) . "/Content/Gallery/" . $_GET['folder']); 

echo $name; 

$data = $file->getPictures($name); 
require 'Views/Gallery.view.php'; 
break; 

Я добавил эхо на третью строку, чтобы узнать, каким будет URL. В приведенном выше правиле все хорошо, и эхо-выходы это:

/var/www/Content/Gallery/Cars 

Пока что так хорошо. Однако, если я вхожу в /../../../../../../../../ вместо «Cars», $ name становится /, и страница все еще показывает корневую папку. Английский не является моим первым языком, поэтому я мог бы не понимать, как работает realpath или что он делает. Из того, что я понял, он удаляет любой экземпляр ../ из заданного URL.

Может кто-нибудь, пожалуйста, скажите мне, что я делаю неправильно?

+1

возможно дубликат [Предотвращение обходных в PHP, но позволяет пути] (http://stackoverflow.com/questions/4205141/prevent-directory-traversal-in-php-but-allow-paths) –

+1

Вот почему PHP получает плохой рэп: \ –

+0

@Mike почему? 'realpath()' не был предназначен для борьбы с атаками обхода каталога; и не претендует на это –

ответ

1

Из того, что я понял, он удаляет любой экземпляр ../ из заданного URL.

Нет, это не то, что он делает. Это не для URL-адресов, это для путей. Он просто преобразует путь и расширяет ../ в правильную папку. Он не удаляет их, он решает их - это означает, что он вычисляет то, что обозначает ../, и изменяет путь к нему.

Он также изменяет/на \ на Windows.

realpath

Realpath() расширяет все символические ссылки и разрешает ссылки на символы «/./», «/../» и экстра «/» во входном пути и возвращает канонизированный абсолютный путь к файлу ,

+0

Спасибо, я был смущен примером на этой странице. Там пример выводит «echo realpath (« ./../../ etc/passwd »); как «/ etc/passwd». Как я могу остановить обход каталога? – ohyeah

+0

Прочтите пример снова. До этого он перемещается в каталог. Относительно этого каталога '' ./../../ etc/passwd'' можно преобразовать в '/ etc/passwd' – Jessica

6

realpath() только недостаточно для борьбы с обходом каталога.

Что вы описываете, это то, что он предназначен для этого: он переводит относительные вещи, такие как ../ в фактический путь к каталогу.

Тем не менее, для обеспечения безопасности вы можете взять путь ed и посмотреть , является ли он еще ребенком безопасного базового пути. Если это не так, кто-то пытался проникнуть в каталог, они не имеют никакого бизнеса, находящегося в:

$name = realpath(dirname(__FILE__) . "/Content/Gallery/" . $_GET['folder']); 

// The safe root directory. 
$safe_root = dirname(__FILE__) . "/Content/Gallery/"; 

// Check whether realpath() result is still inside /Content/Gallery 
if (substr($name, 0, strlen($safe_root)) != $safe_root) 
    die ("Possible directory traversal attack");