about UTF-7 XSS Cheat Sheet

おくればせながら下記を拝見しました。

  • Specify charset clearly (HTTP header is recommended)
  • Don't place the text attacker can control before <meta>
  • Specify recognizable charset name by browser.

上記のような対策を必要とするサイトでは放置しておけばUTF-7系のXSS以外でもXSSの危険性は存在しうると思われます。ですので…

あと、ヤマガタさんの反応を読みながら思ったんですが、一般的なXSS対策で「<」「>」などを「&lt;」「&gt;」にエスケープするように、機械的に「+」を「&#x2b;」にエスケープしてやれば、万が一のときでもUTF-7によるXSSを防げるような気もしたんですけど、あまり深く考えてないのでもうちょっと再考してみますです。

という対策は対UTF-7系のXSSのみに有効かもしれませんけれども他のケースを防ぐことにならないかもしれません。

脳内PoCのみで検証はしていませんが、例えば以下のような攻略ルートが考えられないでしょうか。

  1. title要素にISO-2022-JPエンコードを誘起させるようなものを仕込む
  2. 別の要素ないし属性において、ISO-2022-JP特有のエスケープシーケンスを中途半端に混ぜた危険文字列をつっこむ
  3. するとXSSブラックリストを通過してしまう

ISO-2022-JPエンコードにおける半端なエスケープ符号がブラウザによってはHTMLのパース前に無視されてしまう仕様がありうるのでXSSを狙うアタッカーサイドに攻略方法を考えてみる余地を与えかねません。上記の脳内実験はほんの一例です。

なお、ISO-2022-JPにおける半端なエスケープ文字がブラックリストを通過しうる件は、すでに複数の箇所で公知になっています。そもそもISO-2022-JPを使っているページが少ないのであまり話題にはなっていないようですけれども…公知の一例はこの文章の末尾に引用させて頂いています。

上であげた攻略ルートは、瞬間的に思いついたあくまもでも脳内のPoCに過ぎませんし実証もしていません。大変に申し訳ありません。ですけれど、ひとつの考え方として申し上げたいことは、charsetは仕様にしたがってしかるべく設定しておくことが絶対に必要なのであって、それをサボってしまうと余計な心配事が潜在的に発生しうるということなのです。

ご参考までに以下を併せてお読みくださいませ。

ASCII のバイト列を ISO-2022-* でうかつに解釈すると危険なケースというのは、 <ESC(Bscript> みたいなケースなのだが、これってもともと ASCII で安全か? と言われると、未エスケープな文字が残っている時点でそもそも微妙……。 ISO-2022-* はある意味で ASCII 上位互換になっていて、主な問題は「ASCII の特殊文字が文脈によっては特殊文字として扱われない」ということと、上記のような元々微妙なバイト列がシーケンス消滅によって脆弱になるケースなので、 UTF-7の「ASCII の非特殊文字が文脈によっては特殊文字として扱われる」*1ケースとは取るべき対策が異なるのではないか。

なお、上記の大岩さんによる公知に先立って、えむけいさんが要請したことにより、Firefoxでは、半端なエスケープシーケンスが消えてしまう現象がずいぶんと昔に対策済みとなっているようです。と考えていたのですけれどコメントでえむけいさんからいただいた情報によれば修正は完全ではないようです。私の確認ミスでした。IEなど他のブラウザについて要検証です。ISO-2022-JPな動的なページを作り出しているウェブアプリケーションは、UTF-7周りの話題とは切り離して別途XSS対策に漏れがないかどうか検討が必要かもしれません。…そんなサイト見たことないですけれど。