$_SERVER['REQUEST_URI']
содержит запрошенный путь URI и строку запроса, как он появился в HTTP request line. Поэтому, когда запрашивается http://example.com/foo/bar?baz=quux
, и сервер передает запрос в файл сценария /request_handler.php
, $_SERVER['REQUEST_URI']
все равно будет /foo/bar?baz=quux
. Я использовал mod_rewrite для отображения любого запроса request_handler.php
следующим образом:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule^/request_handler.php
Так за правильность, прежде чем использовать $_SERVER['REQUEST_URI']
в пути файловой системы, вам нужно будет избавиться от строки запроса. Вы можете использовать parse_url
сделать так:
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
Но так как это значение поступает непосредственно из запроса HTTP линии без разрешения до пути, он все еще может содержать символьные сегменты пути, как ..
.
Однако обход трассы не требуется, поскольку запрошенный путь URI уже является абсолютной ссылкой на траекторию, и запрос http://example.com/etc/passwd
должен привести к включению /etc/passwd
.
Так что это на самом деле local file inclusion vulnerability.
Теперь, чтобы исправить это, требуется определенный корневой каталог с использованием method, который вы, chowey, представили, является хорошим улучшением. Но вы на самом деле нужно было бы добавить к ней префикс $basedir
:
$path = realpath($basedir . $_SERVER['REQUEST_URI_PATH']);
if ($path && strpos($path, $basedir) === 0) {
include $path;
}
Это решение обеспечивает несколько обещаний:
$path
либо действительным, разрешен путь к существующему файлу, или false
;
- включение этого файла происходит только в том случае, если
$basedir
является префиксным путем $path
.
Однако это может по-прежнему разрешать доступ к файлам, которые защищены каким-либо другим видом access control like the one provided by Apache’s mod_authz_host module.
Как будет выглядеть запрошенный URI и как вы можете сопоставить запрошенный путь к файлу PHP? – Gumbo
вы можете передать все, что хотите, в request_uri, включая html/javascript. это зависит от ВАС и ВАШЕГО кода, чтобы убедиться, что значение используется безопасно. Вы должны ** НИКОГДА НИКОГДА не позволять пользователю указывать путь, который будет использоваться в include/require, независимо от того, насколько хорошо вы считаете свою безопасность. поскольку он стоит прямо сейчас, они попадают в http: //yoursite.com/http: // malicioussite.com/remote_takeover.php', который выводит php-код в текстовом формате, а ваш сервер полностью и полностью разрушен. –
Ваш код не похож на то, что вы конкретно обеспокоены его безопасностью. Это очень прекрасный пример, позволяющий пользователям вводить данные. Отфильтруйте по крайней мере белый список и найдите больше контрмер, которые не могут быть введены неверными путями. И да, вы можете передавать точки через URI запроса. Это стандартная переменная, которая просто устанавливается или отменяется. –