1

$_SERVER['REQUEST_URI']ファイルをインクルードするために使用することに関連するセキュリティ上のリスクはありますか? ../../..何とかリクエストウリを通過できませんか?

私が考えているのは、次のようなものです。

<?php
$path = $_SERVER['REQUEST_URI'];
$path = preg_replace('~\\.html?$~', '.php', $path);
include $path;
?>

これにより、「.php」パスが「.htm」または「.html」URI に置き換えられ、レンダリングされます。しかし、ここではセキュリティが心配です。

4

4 に答える 4

4

$_SERVER['REQUEST_URI']HTTP 要求行に表示された、要求された URI パスとクエリ文字列が含まれます。したがって、が要求され、サーバーがhttp://example.com/foo/bar?baz=quuxその要求をスクリプト ファイルに渡すと/request_handler.php、. mod_rewrite を使用して、次のようにリクエストをマップしました。$_SERVER['REQUEST_URI']/foo/bar?baz=quuxrequest_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 モジュールによって提供されるような他の種類のアクセス制御を使用して保護されているファイルへのアクセスが許可される場合があります。

于 2013-04-21T07:51:22.477 に答える
0

同じ質問があり、ガンボの答えに基づいて次のことを行うことにしました。

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

$path = realpath(FOLDER_ROOT . $_SERVER['REQUEST_URI_PATH']);

$directory_white_list_array = array('/safe_folder1', '/safe_folder1/safe_folder2');

if ($path && strpos($path, FOLDER_ROOT) === 0 && (in_array(dirname($path), $directory_white_list_array)  && ('php' == pathinfo($path, PATHINFO_EXTENSION)))) {
    include $path;
}else{
    require_once FOLDER_ROOT."/miscellaneous_functions/navigation_error.php";
    navigation_error('1');
}

概要: ディレクトリのホワイトリストと .php 拡張子の制限を追加しました。

于 2013-09-18T16:55:18.180 に答える
0

これは実際には質問に答えません...

リクエスト uri が現在の作業ディレクトリ内の実際の有効なファイルパスを指していることを確認できることに注意してください。realpath関数を使用して、パスを正規化できます。

次のコードはトリックを行います:

<?php
$basedir = getcwd();

$path = $_SERVER['REQUEST_URI'];
$path = preg_replace('~\\.html?$~', '.php', $path);
$path = realpath($path);

if ($path && strpos($path, $basedir) === 0) {
    include $path;
} else {
    return false;
}
?>

ここでは、が で始まるstrposことを確認していました。面白いビジネスはすべて削除されているので、これで安全にディレクトリ内に留まることができます。$path$basepathrealpath../../..$basepath

于 2013-04-20T23:31:16.653 に答える