なぜPHPアプリにセキュリティホールが多いのか?

【スクリプトインジェクション対策14】HTML、CSS、JavaScriptの生成はホワイトリスト方式を利用する

ブラウザに任意スクリプトを実行させる方法は多岐にわたります。

  • 文字エンコーディングを利用する方法
  • ブラウザのバグや仕様を利用する方法
  • Webアプリケーションのバグを利用する方法

ブラックリスト方式の対処が特に困難であるのはブラウザの仕様やバグです。Webサイト運営者は基本的にブラウザのバージョンや仕様/設定を制御することはできません。例えば、FirefoxはE4X(Ecma Script for XML)をサポートしています。この仕様を知らなければブラックリスト方式でスクリプトインジェクションを防ぐことはできません。

例:E4Xを利用したスクリプト実行
a = alert; e4x = {a(1)}

Firefoxの場合、アドレスバーに⁠javascrit:⁠と入力し、JavaScriptコンソールを起動し式を評価するとダイアログが表示され、コードが実行できることが分かります

上記のE4Xを利用した攻撃は、<a>タグを許可し、href属性をブラックリスト方式でチェックしているアプリケーション上でスクリプトインジェクションを許してしまう可能性があります。

さらに困ったことには、セキュリティや仕様上の決まりごとより、仕様に合わないおかしなページでもなんとか表示できるような仕組みが優先された仕様がブラウザに実装されています。例えば、Internet Explorer 6ではタブやヌル文字、改行文字が属性名の途中に入っていても、何もなかったように処理してしまうケースは少なくありません。

ユーザ入力から安全なHTMLドキュメントを出力するためには、一旦ドキュメントを分析し、利用してもよいタグと属性、さらに属性の中身までホワイトリスト化してチェックする以外に安全な方法はありません。

このようなチェックを行う場合、正規表現等を利用して独自のパーサを作ることは行わないほうがよいです。正規表現は非常に強力で便利ですが、少し間違えるだけで不正な入力を許可してしまいます。HTML等のドキュメントはSAXまたはDOMを利用して解析します。

対策のまとめ

  • 不正な文字列を除去しようとしない(サニタイズしない)
  • 不正な文字列を検出しようとしない
  • 正しい文字列だけを許可する(バリデーションする)
  • 出来る限り厳しいバリデーション条件を利用する
  • JavaScriptは動的に生成しないようにする

おすすめ記事

記事・ニュース一覧