XSSによる攻撃(その5)

XSSに関する最後の問題。

問題6. Reflected XSS via AJAX

調査

6問目は「Find a URL that when clicked on will execute a script using one of Jarlsberg’s AJAX features.」。AJAXのバグを突くことにより、ユーザーにURLをクリックさせることで任意のscriptを実行させることができるか。

ajaxを使っている機能を、先ほどのHome画面以外で探す。My Snippets画面にもRefresh機能がある。ここでもAjaxを使っている。該当のコードは以下の通り。

<div class='refresh'><a class='button'
  onclick='_refreshSnippets("xxxxxxxxx", "golem-xiv")'
  href='#'>Refresh</a></div>
function _refreshSnippets(uniqueId, uid) {
_refresh("/" + uniqueId + "/feed.jtl?uid=" + uid, _finishRefreshSnippets);
};

“http://127.0.0.1:8008/xxxxxxx/feed.jtl?uid=golem-xiv”というHTTPリクエストが発行されると、以下のようなレスポンスが返ってくることになる。

_feed(( [ "golem-xiv" ,"Hello, Secure World!" ] ))

つまり、ユーザー名の場所に、任意の文字列を埋め込むことが可能だ。

脆弱性の確認

以下のURLを踏ませることで、スクリプトを実行させることが可能。*1


http://127.0.0.1:8008/2061610856/feed.jtl?uid=<script>alert(document.cookie)</script>

これは、上記URLのレスポンスが以下のような形式で返され、また、content-typeがtext/htmlとなっていることが原因。ブラウザはレスポンスをHTMLとして解釈してしまい、スクリプトが実行される。

_feed((
[
"<script>alert(document.cookie)</script>"
]
))

HTTPのヘッダは、以下のとおりとなっており、確かにcontent-typeがtext/htmlとなっている。

f:id:GOLEM-XIV:20100601225730p:image

対策
エスケープ処理
javascriptの文字列中で<、>を使う場合は、エスケープ処理を行う。各々\x3c、\x3eにエスケープしてやる。
正しいContent-Typeをセットする
レスポンスがHTMLとして解釈されないように、Content-Typeをセットする。RFC4627によれば、JSONのMIME typeはapplication/jsonのようだ。*2jarlsbergのドキュメントでは、application/javascriptを使う、となっている。うーん、どっちが正しいのかな。ただ、jarlsbergのドキュメントによると、ブラウザによっては、content-typeを無視して解釈しようとしてしまうこともあるので、正しいcontent-typeを使うようにする対応だけでは不十分、とのことだ。
正しいエンコード(charset)をセットする
さらに、Jarlsbergのドキュメントによれば、正しいcharsetをセットすることも必要とのこと。もし攻撃者が、何らかの方法でレスポンスのcharsetをUTF7だとブラウザに誤認させることができたとする。すると、+ADw-script+AD4- を<script>に解釈させることが可能(+ADw-と+AD4-は、UTF7で各々<と>に該当する)。IEに依存したWebアプリケーションセキュリティに詳しい説明があった。:

*1: 脆弱性の原因を確信していたわけではなく、色々なコードをuidに入れてみて、偶然脆弱性を確認できました。(^^;)

*2:"The MIME media type for JSON text is application/json."との記載がある。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です