人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPについて質問です。

別ファイルのフォームよりPOSTで['keyword']を受け取り、
あらかじめ作成されている$keyword.phpというファイルに転送するという
趣旨で下記のようなスクリプトを作成しました。

$keyword = $_POST['keyword'];
header("location:$keyword.php");

上記のスクリプトを手直しする形で
必要なセキュリティ対策をすべて教えてください。


●質問者: taroemon
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:keyword PHP スクリプト セキュリティ ファイル
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● pahoo
●10ポイント

確認ですが、POSTで受け取った変数が拡張子を除くスクリプト名 $keyword で、そのスクリプト $keyword.php にジャンプするという趣旨ですよね。


セキュリティ対策というのは、「予想される脅威から、何かを守る」ための対策です。

ご質問のケースでは、単純にジャンプするだけなので、守るべき「何か」は無いように思います。


$keyword 以外にも送信するデータがある、自サイト以外へはジャンプさせたくない等、もう少し具体的な要件をお示しください。

◎質問者からの返答

ご回答ありがとうございます。

質問の説明不足申し訳ありません。


>確認ですが、POSTで受け取った変数が拡張子を除くスクリプト名 $keyword で、

>そのスクリプト $keyword.php にジャンプするという趣旨ですよね。

その通りです。


実際の送り手側はスクリプトは下記の通りです。

<form action="search.php" method='POST'>

<input type="text" name="keyword" size="30" value="">

<input type="submit" size="20" name="submit" value="検索">

</form>


$keyword 以外に送信するデータはありません

自サイト以外へはジャンプさせたくないです。


以上で適切な説明になってるでしょうか?

よろしくお願いします。


2 ● b-wind
●23ポイント
$keyword = $_POST['keyword'];
$ok_keyword = array(
 'aaa' => 'http://www.example.com/aaa.php',
 'bbb' => 'http://www.example.com/bbb.php',
 'ccc' => 'http://www.example.com/ccc.php',
 'ddd' => 'http://www.example.com/ddd.php',
 'eee' => 'http://www.example.com/eee.php',
 'default' => 'http://www.example.com/aaa.php',
);
$url = $ok_keyword[$keyword] ? $ok_keyword[$keyword] : $ok_keyword['default']
header("location:$url");

突っ込みどころがありすぎて困るな。

@IT:Webアプリケーションに潜むセキュリティホール(14)

◎質問者からの返答

これは検索されたとき、当該ファイル名が無い場合の処理ということでしょうか?

ご指摘ありがとうございます。


3 ● pahoo
●50ポイント ベストアンサー

こんな感じでどうでしょう。

なお、「必要なセキュリティ対策をすべて」というのは無理です。極端な話、PHPのバグまではフォローできませんので。

ただ、このスクリプト自体の欠陥に気づいた方がいましたら、遠慮無くご指摘ください。


■要件


//HTTP_REFERERを調べる
$referer = 'http://www.hoge.com/送り手のスクリプト名';
if (strpos($_SERVER['HTTP_REFERER'], $referer) != 0) {
 echo 'ジャンプ元が間違っています';
 exit(1);
}
//念のためスクリプトの長さを制限する
$keyword = $_POST['keyword'];
if (strlen($keyword) > 255) {
 echo '指定されたコンテンツは長すぎます';
 exit(1);
}

//正しいURL書式かどうか調べる(?, # は除く)
preg_match("/(https?:\/\/localhost\/[\-_\.!~\*\'\(\)a-zA-Z0-9;\/:@&=+$,%]+)/", $keyword, $arr);

if (isset($arr[1])) {
 $fname = $arr[1];
 if (fopen($fname . '.php', 'r') == FALSE) { //存在するかどうか調べる
 //PHP5環境なのでfile_existsを使ってもいいかも
 echo '指定されたコンテンツ "' . $fname . '" は存在しません';
 } else {
 header("location: {$fname}.php");
 }
} else {
 echo 'コンテンツ "' . $keyword . '" は指定できません';
}
◎質問者からの返答

ご回答ありがとうございます。

「必要なセキュリティ」というのがこんなにあるとは思いませんでした。

もちろんPHPのバグ修正までは望んでいません。

質問者としてはこれで十分満足しました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ