セキュリティ系の勉強、その他開発メモとか雑談. GithubはUnity触っていた頃ものがメイン Twitterフォローもよろしくです

html属性とXSSの復習

//

XSS問を通じて、HTMLの挙動がよく分かってなかったと思ったので、そこをちょろっとまとめ直しておきます。

お題

とあるXSS問題。

<input type="text" value="" onclick="hoge('「ここに入力文字が入るよ」')" size=20>
    <input type=submit value="send"><br>
<script>function hoge(a){}</script>

f:id:thinline196:20200615153640p:plain:w400

「ここに入力文字が入るよ」の箇所に入力が埋め込まれてレスポンスが返ってくる感じ。ただし、エスケープは以下のようにされます。

「\」→「 \\」
「'」→「 \'」
「"」→「 \"」
「space」→「+」


これに対して私は以下のシグネチャで通った。 "onmouseover=alert(document.cookie);//

最終的に生成されたのはこちら。

<input type=text onclick="hoge('\"onmouseover=alert(1);//')" size=20>

これなんでマウスオーバー動くの。あ、これが自明な方は、得る知識がないと思われるのでブラウザバックで、、、

注意

</>タグ閉じなどを使えそうですが、今回はそこは見ないフリか追加で対策されているものとしてください、、、

調査

"エスケープ

そもそも"エスケープが\"では不十分。属性値を囲っている記号"は、\エスケープしてもその値の終端として解釈される。&quot;エスケープすること。

    test1(esaape to \")
    <input type="text" onclick="\" hoge="v" size=20>
    
     test2(escape to &quot;)
    <input type="text" onclick="&quot; 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>


シンタックスハイライトで見えているかと思われますが、test3test4onmouseoverの値の範囲が違うと思います。

html//コメントアウトと解釈しませんが、今回の例test3では、onmouseoverから文字が連続しているため//スクリプト側でコメントアウトと解釈されていました。ですので今回はコメントアウトすることで後ろの入らない文字を消していました。

test4は無理やりタグを閉じてしまったので、後ろはただの文字として表示されます。

余談

&#92;(バックスラッシュの意)のような数値文字参照?(っていうんですかね?)を使ったりなども可能。で、下のシグネチャなどもok

&#92;');alert(1);//

この場合、'\'エスケープされるが、\\'となるため\エスケープ対象となり結果的に\'と解釈され、hogeメソッドの引数内をうまく閉じている。