BitArts Blog

ロードバイク通勤のRubyプログラマで伊豆ダイバー。の個人的なブログ。

UTF-7によるクロスサイトスクリプティング

少し前から知られている脆弱性ですが、どうもかなり多いっぽいので書いておきます。この問題の怖いところは、通常知られているXSS対策(HTMLメタキャラクタのエスケープ、いわゆるサニタイズ)ではすり抜けてしまうところです。

UTF-7というのはUnicodeの一種で、すべての文字を7bit ASCIIだけで表現するエンコーディングです。

たとえば「<script>alert('XSS')</script>」をUTF-7エンコーディングして、HTML内に埋め込むと、こんな感じになるとします。

<body>
<p>Hello,
+ADw-script+AD4-alert('XSS')+ADsAPA-/script+AD4-</p>
</body>

これをIEで読んでみると分かりますが、動いちゃいます。(((;゚Д゚)) 「<、>」も「"」も使っていませんから、今までのサニタイズは効きません。

原因はこうです。UTF-7の文字列が埋め込まれているもんだから、Webブラウザは、「UTF-7のコンテンツなんだ」と自動識別して、UTF-7としてレンダリングしてしまっているというわけです。(Firefoxでは大丈夫)

しかし対策はとても簡単。HTMLコンテンツを出力する際にContent-Typeに適切なcharsetを指定するだけです。charsetを指定しなかったり、誤ったcharsetを指定していると、この問題が発生します。特にcharsetの間違いには注意しましょう。ブラウザが認識できるcharsetを指定することが重要です。たとえば「EUC-JP」「Shift_JIS」「UTF-8」は正しいですが、「EUC_JP」「SJIS」「UTF8」などは誤りです。

対策は簡単とは言え、charsetを返していないWebアプリというのは、世の中にはいくらでもあるのではないかと思います。日本語コンテンツを返すWebアプリでは文字コード自動認識が適切に動くので、あまり問題にならないかもしれませんが、ASCII文字だけを返すページは要注意です。日本語サイトであっても、エラー画面などは危険かもしれません。ぜひ点検してみてください。

こちらの記事も追記しておきました。↓

当社の脆弱性診断サービスでは、この問題に関しても検出します。