Подтвердить что ты не робот

Sanitize путь к файлу в 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", будет проблемой, но интересно, какие другие вредоносные входы я должен ожидать и как их предотвратить.

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

Ответ 4

Решение с помощью OP:

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

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