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脆弱性として届け出てくださいね。