Очистить путь к файлу в PHP - PullRequest
24 голосов
/ 16 декабря 2009

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

    $path = "/home/gsmcms/public_html/central/app/webroot/{$_GET['file']}";


    if(file_exists($path)) {
        echo file_get_contents($path);
    } else {
        header('HTTP/1.1 404 Not Found');
    }

Сверху головы я знаю, что ввод, такой как '../../../../../../etc/passwd', будет проблематичным, но мне интересно, какие другие вводные данные я должен использовать ожидать и как их предотвратить.

Ответы [ 7 ]

34 голосов
/ 16 декабря 2009

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

12 голосов
/ 16 декабря 2009

Используйте basename вместо того, чтобы пытаться предвидеть все небезопасные пути, которые может предоставить пользователь.

8 голосов
/ 31 октября 2014

Решение по ОП:

$baseDir = "/home/gsmcms/public_html/central/app/webroot/"; 
$path = realpath($baseDir . $_GET['file']); 

// if baseDir isn't at the front 0==strpos, most likely hacking attempt 
if(strpos($path, $baseDir) !== 0 || strpos($path, $baseDir) === false) { 
   die('Invalid Path'); 
} elseif(file_exists($path)) { 
   echo file_get_contents($path); 
} else { 
   header('HTTP/1.1 404 Not Found'); 
   echo "The requested file could not be found"; 
} 
6 голосов
/ 16 декабря 2009

Если вы можете, используйте белый список , например, массив разрешенных файлов, и проверьте введенные данные: если файл, запрошенный пользователем, отсутствует в этом списке, отклоните запрос.

4 голосов
/ 16 декабря 2009

Здесь существует дополнительный и значительный риск для безопасности. Этот сценарий будет вставлять источник файла в выходной поток без какой-либо обработки на стороне сервера. Это означает, что весь ваш исходный код любых доступных файлов будет просочиться в Интернет.

2 голосов
/ 08 марта 2016

Даже если вы используете realpath, вы все равно должны удалить все "..." перед его использованием. В противном случае злоумышленник может прочитать всю структуру каталогов ваших серверов с помощью грубой силы, например, «valid_folder /../../ test_if_this_folder_name_exists / valid_folder» - если приложение принимает этот путь, злоумышленник знает, что папка существует.

0 голосов
/ 05 марта 2017

Чтобы удалить все /. /.. или \. \ .. и преобразовать во все косые черты, потому что разные среды будут принимать прямую косую черту. Это должно обеспечить довольно безопасный фильтр для ввода пути. В вашем коде вы должны сравнивать его с родительскими каталогами, доступ к которым вам не нужен на всякий случай.

 $path = realpath(implode('/', array_map(function($value) {return trim($value, '.');}, explode('/', str_replace('\\', '/', $path)))));  
...