anti-XSS system (1)

Date 2006-06-20 13:16:00 | Category: PHP

in englishin japanese
XSS (cross site scripting)は、きわめて一般的でありながら、チェーンによって極めて強力な攻撃に転じうる、怖い脆弱性と言えます。
特に怖いのが、JavaScriptのXMLHttpRequestを利用する攻撃で、同一ホストのどこか一箇所にXSSがあるだけで、クッキー流出やCSRF対策の無効化がなされます。ホストさえ同一なら、どこでもOKというのが怖いところで、クッキーのパスや、CSRF対策のチケットやリファラーチェックなども、ほとんど意味をなさなくなってしまいます。
(IEのバグで、Ajaxの技術を応用すれば、別ホストでも上記と同様の攻撃が可能、というのはここでは言及しません。明らかにIE側で修正すべき穴であり、Webアプリケーション側では手も足も出ません。)

とにかく、XSSを体系的に潰すことが何より重要だというのが、結論です。

本来、XSSというのは、正しいリクエスト処理・表示処理をしていれば防げるものではありますが、人間とは、ポカミスをしでかす生き物です。テンプレートシステムなどの、自動的にhtmlspecialchars()をかけるブラックボックス化、というのも手ではありますが、そういうブラックボックスを用意しても、HTMLを直に出力したい場面が必ず存在する以上、ブラックボックスを経由しない部分でポロっとXSSをだす可能性は大だと私は考えています。

テンプレートシステムなどではなく、Webアプリケーション全体を守ってくれる「大きな傘」のようなもの。これこそが、ほとんどのサイトに求められるXSS対策ではないでしょうか。

これだけ書くと、mod_securityのような「入口」でのチェックを思い浮かべたかもしれません。それも有効な手段ではあるでしょう。しかし、mod_securityでリクエスト制限を行った場合、面倒な問題が発生します。

例えば、"<script" という文字列を含むリクエストを禁止してしまう場合、JavaScriptの開発フォーラムが事実上機能しなくなってしまうでしょう。

かといって、obフィルターなどの「出口」側で "<script" を禁止してしまうと、今度は、本来機能して欲しいJavaScriptが死んでしまいます。


私自身、ここでしばらく悩んでいたのですが、ふと、ベストな解法が思い浮かびました。

「入口」で怪しいリクエストを見つけたらそれを覚えておき、「出口」でそのまま出力されていないかをチェックする

これこそが、「大きな傘」たり得る、XSS対策です!
通常、"<script" などのXSS攻撃に特徴的な文字列がリクエストされることは極めて稀なので、そういう特殊な状況でのみ、ob_start()で「出口」チェックを登録する、という方法で、パフォーマンスへの影響も避けられます。

実際のコーディングは(2)に続きます。




You can read more news at PEAK XOOPS.
http://xoops.peak.ne.jp

The URL for this story is:
http://xoops.peak.ne.jp/md/news/index.php?page=article&storyid=126