XSSの出題 回答編
3月7日の出題の解説。
例題のWebアプリケーションもどきは、クエリストリングとして与えた文字列が <input> の value にセットされる、という仕様です。
例えば、"abc"を与えた場合には、出力される HTML は
<input type=text id=q name=q size=40 value=abc>
となります。value属性が引用符で囲まれていませんが
- 「&」「>」「<」「"」「'」の各文字はHTMLエスケープされる
- スペースは削除される
- 0x21から0x7eの範囲にない文字も削除される
というフィルタがかかっているため、一見するとスクリプトの挿入は無理に思えます。
ところが、IE ではバッククォート(`)が引用符として利用可能であるため、これを利用すると簡単にイベントハンドラなどが挿入できます。
ということで、回答としてはこんな感じのクエリを与えることでIE上でスクリプトが発動します。
http://openmya.hacker.jp/hasegawa/test/jxss.html?%60%60onmouseover%3Dalert%28document.location%29
実際にスクリプトを動かしたところ。
もちろん、onmouseover ではなく style=xss:expression(...) のような、まったくの操作なしでのスクリプトの発動も可能です。
で、ここからが本題
IE で例えば
<input type="text" value="`abc`size=200">
のようなHTMLを表示させたとします。value 属性はダブルクォートで囲まれていますので、当然「`abc`size=200」という文字列になります。ところが、これを印刷プレビューさせてみると
a) value にスペースが入っていない場合は前後の "" は消える。
b) バッククォート(`) が引用符として働く
という2つのおかしな挙動が重なって、size 属性が有効となり、input のサイズが200になってしまいます。
さて、これを利用してXSSさせることは可能か、ということでいろいろ検証してみました。
<div title="``onlayoutcomplete=document.writeln(document.location)"> <div title="`abc`onbeforeprint=document.writeln(document.location)"> <div title="`abc`onafterprint=document.writeln(document.location)">
のようなタグを入れてみたりしたのですが、スクリプトは動きませんでした。残念というか安心というか。
もし、この手法を使ってスクリプトの発動が可能だった場合には、ちゃんとIEの脆弱性として届け出てくださいね。