ここから本文です

PHPでDNSリバインディング攻撃への対策を行う場合のチェック式はこれで問題ないで...

sounisi5011さん

2014/4/1101:40:43

PHPでDNSリバインディング攻撃への対策を行う場合のチェック式はこれで問題ないでしょうか?

お世話になります。

以前の質問の回答の1つに、DNSリバインディング攻撃への対策を行う必要があるというものがありました。
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1212686005...

PHPでの実装としては、Hostヘッダのチェックを行えば良いという解釈に基づき、
次のようなコードを考えました。

if(!isset($_SERVER['HTTP_HOST']) || $_SERVER['HTTP_HOST']===$_SERVER['SERVER_NAME'])

Hostヘッダがある場合、$_SERVER['SERVER_NAME']と一致するかチェックしているコードです。
しかし、私の環境ではDNSリバインディング攻撃を再現できない(or その方法が分からない)ので、
このコードで正しいのか判断しかねます。
意見を聞かせて下さい。


このコードで合っているか悩む一番の理由は、$_SERVER['SERVER_NAME']の値についてです。
公式マニュアルでは “現在のスクリプトが実行されているサーバーのホスト名です。” と記述されているため、
実行しているサーバのホスト名を返すものと判断して良いと思うのですが、
この値がHostヘッダの影響を受け変化するのかどうかが不明です。
PHPの内部実装的に、$_SERVER['SERVER_NAME']は信頼出来る値なのでしょうか?

補足$_SERVER['SERVER_NAME']はHostヘッダの影響を受けるのですか・・・

将来作成するかもしれないライブラリなどに備え、サーバのホスト名などはできるだけ自動取得したかったのですが、それは出来ませんか?

ちなみに、このコードを使う予定のレンタルサーバはバーチャルホストのようなので、無理に作る必要は無くなりました。
・・・が、ノウハウとして知っておきたいです。

閲覧数:
836
回答数:
1

違反報告

ベストアンサーに選ばれた回答

htokumarさん

編集あり2014/4/1408:24:57

Hostヘッダの妥当性確認に $_SERVER['SERVER_NAME'] を用いる方法はよくありません。
その理由は、多くの場合、$_SERVER['SERVER_NAME'] は $_SERVER['HTTP_HOST'] と同じ値を示すからです。すなわち、テストの意味がありません。
もう少し厳密に言うと、Apacheの UseCanonicalName というディレクティブが On の場合、$_SERVER['SERVER_NAME'] は Apacheの ServerName を返します。これは期待された挙動です。一方、UseCanonicalName がOffの場合は、$_SERVER['SERVER_NAME'] はHostヘッダ(ポート番号は除く)を返します。
そして、UseCanonicalName のデフォルト値は、Apache 2.0までは On、Apache 2.2以降は Off です。
このように、$_SERVER['SERVER_NAME']は環境に依存するため、この種のチェックには使いづらいです。
では、どうすればよいかですが、以下のようにハードコーディングでもよいのではないでしょうか?

if(!isset($_SERVER['HTTP_HOST']) || $_SERVER['HTTP_HOST']==='example.jp')

あるいは、ホスト名を定数として宣言しておいてもよいでしょう。

なお、多くのレンタルサーバーのように、名前ベースのバーチャルホストを使っている場合は、上記のチェックは必要ありません。正規のホスト名でなければ、Webサイトにアクセスできないからです。

【追記】
サーバーのホスト名を取得する安定した方法は見あたりません。
ここで、ホスト名として何を取得するかですが、考えられる候補には下記があります。

・Apache の ServerName 設定
こちらは、PHPから簡単に取り出す方法が見あたりませんが、Apacheの UserCanonicalName を On にして、$_SERVER['SERVER_NAME'] から取得することは可能
・OSのホスト名
gethostname() あるいは php_uname('n') で取得できます。しかし、通常OSのホスト名は通常Webサーバーのホスト名(FQDN)とは一致していないと思いますので、これは駄目でしょう。

スクリプトの実行環境が UserCanonicalName On とは限らないので、アプリケーション側で定数宣言する方法が一番無難であると思います。
なお、UserCanonicalName On を前提とする方法はセキュリティ的にはお勧めできません。そのスクリプトをUserCanonicalName Off の環境にもっていくと、チェックが無効になってしまうからです。セキュリティチェックのプログラムは、設定がおかしい場合は、安全側、すなわちプログラムが動かないようになるべきです。UserCanonicalName Off の環境に持って行ったとたんにチェックが働くなる状態は、潜在的な脆弱性であると考えられます。

質問した人からのコメント

2014/4/17 13:07:01

うーん、そうですか・・・
となると、このチェックを組み込んだアプリケーションなどを作る際、
管理画面などから正しいホスト名を設定させる必要がありますね・・・

回答、ありがとうございました!

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問や知恵ノートは選択されたID/ニックネームのMy知恵袋で確認できます。