9

次のコードを使用しても安全ですか:

require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $_GET['page'] . ".php") 
4

5 に答える 5

12

いいえ、安全ではありません。なんで?

2 つのドット/../のシーケンスは 1 つのディレクトリを意味するため、攻撃者はシステム上のあらゆるものを含める可能性があります$_SERVER['DOCUMENT_ROOT']。(秘密/機密のOS構成ファイルを意味する不幸な構成で。)

悪意のある入力を防ぐために、許可された値を IF または SWITCH する必要があります。例:

switch($_GET['page']) {
     case 'welcome': $page='welcome';
     case 'shop': $page='shop';
     default: $page='index';
}
require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $page . ".php")

in_array()少し簡単なろ過もチェックしてください。

于 2012-07-26T19:44:59.633 に答える
2

StackOverflow には、 PHP でユーザー入力をサニタイズする方法に関する便利な Q&A があります。数年前ですが、原則はまったく変わっていません。

簡単に言えば、最初から問題を回避できれば、より良い結果が得られるということです。

これをどのように使用しようとしているのかをお知らせください。改善のための提案を提供できる場合があります。

于 2012-07-26T19:47:50.860 に答える
1

安全ではありません。許可された値で配列を使用できます。例えば

$allowed_pages = array('index', 'test', 'my_page')
if (!in_array($_GET['page'], $allowed_pages)){
    echo 'good bye';
    die();
} else {
   //
}
于 2012-07-26T19:48:23.800 に答える
-1

ページディレクトリ内のすべてのファイルを信頼する場合は、次を試してください。

if (in_array($_GET['page'],glob("/pages/*.php"))) {
   require($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $_GET['page'] . ".php");
} else echo "Nice try hacker!";

アップロードされたファイル名を消去するために使用する関数の一部を使用した別のソリューションを次に示します。

オプション #2 ダニエル、ロックに感謝します。

$page = preg_replace('/[^a-zA-Z0-9_ %\[\]\.\(\)%&-]/s', '', $_GET['page']);
$filename = $_SERVER['DOCUMENT_ROOT'] . "/pages/" . str_replace("/",'',$page) . ".php";
if (file_exists($filename)) {
    require($filename);
} else echo "Nice try hacker!";

これは、ファイル名に特殊文字が含まれていない場合にのみ機能することに注意してください

于 2012-07-26T19:54:55.180 に答える
-3

regExp を使用して$_GET['page']!

于 2012-07-26T19:46:24.540 に答える