半端な文字と半端な変換が引き起こすXSS

反応が遅すぎるんですが、@ITで連載中の星野君のWebアプリほのぼの改造計画がどんどん斜め上に向かっていて素晴らしいです。


マルチバイト文字絡みでXSSと言えば、ひとつ役に立ちそうもない話が。

複数ページに渡って入力項目がある場合、前のページで入力された値をhiddenで渡す方法が良く使われます。
その場合、HTMLには

<input type="hidden" name="param1" value="あ">
<input type="hidden" name="param2" value="い">
<input type="hidden" name="param3" value="う">
<input type="hidden" name="param4" value="え">
<input type="hidden" name="param5" value="お">

こんな感じでhiddenのタグが並ぶ事になります。
この時、(入力された値が入る)valueの内容を適切に変換しないとXSSが発生し得るわけですが、適切な変換というのは何でしょうか。
一般的には「<>&"'」を全て文字参照にすれば良いとされています。しかし、もし仮に「&"'」だけを文字参照にしていた場合*1XSSが発生する可能性があります。

先ほどの例では、param1に「●」がparam2に「><script>alert(1)</script>●」が渡され、Shift_JISとして表示された場合にalertが動作する場合があります。(●は0x8F)
どうしてそうなるのか、詳しい理由はよくわかりませんが、Windows上のIE6,Firefox1.5,Opera9及びMacOS上のFirefox1.5ではalertが動作しました。Safariは無事です。

それで、果たしてこんな半端な変換を行っているケースがあるのかどうかなのですが、かつてとある銀行のWebサイト上で実際に「<>」がそのまま出力されているのを見た事があります。
ただし、param2のタグが終わった後、同じ行に「"」があると動かなくなるみたいで、その銀行のWebサイトではこのパータンのXSSは動作しませんでした。

そういうわけなので、半端な変換は止めましょう。

なお、その銀行はすでにありません。

*1:そもそもHTML的に正しくない記述ができるかもしれません