2007-07-17
■[SECURITY] そろそろ UTF-7 について一言いっとくか

UTF-7を利用したXSSは、charset が指定されていない場合に発生すると考えられていますが、少なくとも Internet Explorer においては、これは大きな間違いです。正しくは、Internet Explorer が認識できる charset が指定されていない場合であり、charsetが付加されていても、IEが認識できない文字エンコーディング名である場合にはXSSが発生します。
例えば、次のような HTML は(HTTPレスポンスヘッダで charset が明示されていない場合)IEが文字エンコーディング名を正しく認識できないため、その内容からUTF-7と解釈されるためにスクリプトが動作します。"utf8"という表記はUTF-8の慣用的な表現ではありますが、ハイフンが抜けており正しい表記ではありません。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8"> </head> <body> +ADw-script+AD4-alert(document.location)+ADsAPA-/script+AD4- </body> </html>
IE が正しく判別できる文字エンコーディング名の一覧は、レジストリの HKCR\MIME\Database\charset 以下に定義されています。"utf8"のような、ここに列挙されていない文字エンコーディング名は、IEでは正しいエンコーディング名を認識できないため、Webアプリケーションがそのような文字エンコーディング名を送出している場合には、攻撃者はCVE-2007-1114などと組み合わせることにより、XSSを発生させることが可能となります。
例示した"utf8"以外に、国内のWebアプリケーションにありがちな、IEが認識できない文字エンコーディング名としては以下のようなものがあります。
- jis
- ISO-2022-JPの慣用的な表現
- MS932 / CP932 / CP942C
- Java上の Shift_JIS の類似エンコーディング
- Windows-31J
- Windowsで使用されているコードページ932のIANA正式登録名。これが認識できないのはどう考えてもIEが悪いと思います。
Webアプリケーション上で文字エンコーディングをハードコーディングしている場合だけでなく
http://example.com/?q=abcd&charset=euc-jp
のように、パラメータにより外部から文字エンコーディングを指定可能なものも見かけます。指定された文字エンコーディングに従いパラメータを解釈するだけでなく、出力も指定された文字エンコーディングに従って変換するようなものです。こういった類のWebアプリケーションにおいて前述した CP932 などの文字エンコーディング名を許容している場合には、XSSが発生します。
http://example.com/?q=%2BADw-script%2BAD4-alert%28document.location%29ADsAPA-/script%2BAD4-&charset=CP932
エラーページなども含め、あらゆるコンテンツでは文字エンコーディング名として Shift_JIS や UTF-8 といった問題のない名称を使用するように心がけましょう。
よいお知らせ
上記の内容について、Microsoftに対して Internet Explorer の仕様改善の要望として提出したところ*1、脆弱性として届け出なおして欲しいとの返答を得ました。そこで、改めて脆弱性として届け出たところ、次のような回答を頂きました(要旨抜粋)。
本事象につきましては、既に公開されている内容と同一であり、弊社では Internet Explorer の脆弱性と判断しております。
弊社では、本事象の対応が必要であると認識しており、現在、対応策を検討中でございます。
将来的には、上記のような状況でのXSSの発生が減る方向にIEが修正される、ということです。まさか、MicrosoftがIEのこのような挙動に対して脆弱性として判断するとは思っていなかったので実に意外でした。
2007年07月18日追記
セキュリティホール memoにて「IE はそれを UTF-7 と誤認する場合があり」と書かれていますが、IE7においてはCVE-2007-1114を利用することで、ほぼ確実にUTF-7と誤認させること、すなわちXSSを発生させることができます。なので「場合があり」というほどぬるい状況ではなく、この方法によるXSSを防ぐためには、Webアプリケーション側は必ずIEが識別可能な charset を送出してやらなければなりません。
*1:Microsoftの言う「セキュリティの脆弱性」の定義には当てはまらないと考え、仕様改善の要望とした。
- http://d.hatena.ne.jp/ripjyr/20070717
- http://d.hatena.ne.jp/comiken/20070717
- http://d.hatena.ne.jp/ripjyr/20070723
- 葉っぱ日記 - ブラウザによって異なる画像を表示する
- 葉っぱ日記 - 2007年のクロスサイトスクリプティングを振り返って
- 電脳戦士ハラキリ -SE道とは死ぬ事と見つけたり- - Javaによるweb開...
- 葉っぱ日記 - Google.comでXSS
- まっちゃだいふくの日記★とれんどふりーく★ - [http://japan.zdne...
- 葉っぱ日記 - 安全なウェブサイトの作り方 改定第3版
- 葉っぱ日記 - Webアプリケーションテスト手法
- 徒然日記 - ハッキング研修
- Web系がおもしろい。 - Java/JSPやってるメモ1
- 454 http://www.st.ryukoku.ac.jp/~kjm/security/antenna/
- 310 http://www.pluto.dti.ne.jp/~rinou/
- 296 http://www.st.ryukoku.ac.jp/~kjm/security/memo/
- 296 http://www.st.ryukoku.ac.jp/~kjm/security/memo/2007/07.html
- 294 http://b.hatena.ne.jp/hotentry
- 270 http://d.hatena.ne.jp/
- 238 http://reader.livedoor.com/reader/
- 117 http://b.hatena.ne.jp/
- 117 http://b.hatena.ne.jp/HiromitsuTakagi/
- 113 http://ja.reddit.com/
しかもその内容は実際には使われない(mlang.dllにハードコーディングされている)ので、個人的に回避しようと思ってレジストリを書き換えても役に立ちませんね。