$_SERVER['REQUEST_URI']
HTTP 要求行に表示された、要求された URI パスとクエリ文字列が含まれます。したがって、が要求され、サーバーがhttp://example.com/foo/bar?baz=quux
その要求をスクリプト ファイルに渡すと/request_handler.php
、. mod_rewrite を使用して、次のようにリクエストをマップしました。$_SERVER['REQUEST_URI']
/foo/bar?baz=quux
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
.
つまり、これは実際にはローカル ファイル インクルージョンの脆弱性です。
これを修正するために、chowey が提示した方法を使用して特定のルート ディレクトリを要求することは、良い改善です。しかし、実際には次のようにプレフィックスを付ける必要があります$basedir
。
$path = realpath($basedir . $_SERVER['REQUEST_URI_PATH']);
if ($path && strpos($path, $basedir) === 0) {
include $path;
}
このソリューションは、いくつかの約束を提供します。
$path
既存のファイルへの有効な解決済みパス、またはfalse
;
- そのファイルのインクルードは、
$basedir
が のプレフィックス パスである場合にのみ発生します$path
。
ただし、これにより、Apache の mod_authz_host モジュールによって提供されるような他の種類のアクセス制御を使用して保護されているファイルへのアクセスが許可される場合があります。