Очистить путь к файлу в PHP


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

    $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 24

7 ответов:

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

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

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

$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"; 
} 

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

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

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

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

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