PHP безопасный корень - PullRequest
       5

PHP безопасный корень

6 голосов
/ 22 августа 2010

Мой друг обнаружил проблему в моем скрипте, он дает доступ к корневым файлам.

Этот URL дает файл passwd:

http://site.com/attachment.php?file=../../../../../../etc/passwd

Как избежать этой дыры в безопасности?

Ответы [ 4 ]

14 голосов
/ 22 августа 2010

Не загружайте файлы с помощью URL String .... Определите уникальные идентификаторы для обозначения файла, а не пути.

Возможно, вы видели такие загрузки http://www.mysite.com/download.php?id=23423, что они делают, используйте этот идентификатор,извлечь имя файла и путь из БД, а затем загрузить его.

4 голосов
/ 22 августа 2010

Есть несколько разных решений.Если может быть только имя файла, будет работать решение basename ().

Однако, если это может быть путь, необходимо более сложное решение

//assume current directory, but can be set anything. Absolute path of course
$basedir   = dirname(__FILE__);
//assume our files are below document root. 
//Otherwise use it's root dir instead of DOCUMENT_ROOT
$filename  = realpath($_SERVER['DOCUMENT_ROOT'].$_GET['file']);
if (substr($filename,0,strlen($basedir)) !== $basedir) {
  header ("HTTP/1.0 403 Forbidden"); 
  exit; 
}

, также есть полезноеВариант конфигурации PHP open_basedir

3 голосов
/ 22 августа 2010

Вы можете использовать realpath() и dirname() для проверки URL-адресов по $_SERVER['DOCUMENT_ROOT'] (или любой другой каталог, «безопасный» для загрузки).

Если результат realpath() указывает вне безопасного каталога, вы можете отклонить запрос на загрузку.

Существует также директива безопасности open_basedir (и опция времени выполнения с 5.3).

1 голос
/ 22 августа 2010

Полагаю, у вас есть каталог, в котором хранятся все вложения.

Просто проверьте, находится ли файл в вашем каталоге.

 // http://www.php.net/manual/en/function.basename.php
 // http://cz.php.net/manual/en/function.file-exists.php 
 if (file_exists($attachments_path . "/" . basename($_GET['file'])) {
  // do work
 }

Starx опубликовал решение, которое кажется хорошим. Это может быть сделано без базы данных, хотя. Если кто-то загрузит файл, вы можете сохранить его как md5($filename).$extension и использовать свой скрипт.

...