XSSフィルターの評価について
たとえば以下のように、script要素の中に第三者の記述(=$userdata)が埋め込まれるとします。
<script type="text/javascript" >
$userdata
</script>
防衛観点からみれば、こんなことが可能なようでは、まず駄目というのが定説です。まぁそれでもなんらかのフィルターがあればまだましだろう、という考え方もあろうかと思います。私はそのような隙のある考え方にはおおいに問題があるとかねてより考えております。ですから、強力なフィルターを脳内で考えてはそれを打破してみる、といった遊びを時々行うわけです。変なフィルターに頼ることだけでは駄目である、という事実を知りたいのですね。
記号だけでJavaScriptを実行する
記号だけでJavaScriptを実行するというid:hasegawayosukeさんの最近の素晴らしいアイデアにはほとほと感服しました。文字列を拾ってブラックリストにのっていればこれを拒否するタイプのフィルターは無意味であると高らかに宣言しているからです。
遊びでやってみよう::記号禁止一歩手前でJavaScriptを書く
以下の断片が含まれるHTMLを吐き出すウェブアプリがあったとします。
<script type="text/javascript" >
$userdata
</script>
において、$userdataには以下のフィルターがかかっています。text/htmlでcharsetがiso-8859-1の世界で考えてください。
- 数字オッケー
- 英小文字オッケー
- 英大文字オッケー
- スペースオッケー
- 改行オッケー
- 等号(=)オッケー
- 上記以外は全部改行に変換される
- SGMLやiso-8859-1に不適合なら改行に変換される。たとえば[0x00]など
等号以外の記号は全部禁止です。かなり安全に見えますが、実は、以下のようなことが可能です。
document.URL(もしくはdocument.cookie)を読み出して悪意あるサイトにその内容を送りつける。
実際に、Firefoxの最新版で今朝、確認しました。ver 1.5.0.8のバージョンでも確認しました。(※)
コードは今回記しませんが、皆さんちょっと考えてみませんか?
注※昨夜、記号としてドット(.)も必要でしたが今朝方それを不要であると気がついたのです。ユーレカ!