Developers Summit 2012で「趣味と実益の脆弱性発見」を聞いてきた

デブサミ 2012(codezine.jp)に行ってきました。はせがわようすけ(Twitter)さんの「趣味と実益の脆弱性発見(www.slideshare.net)」が興味深かったので、感想などを。

顔文字JavaScriptで会場の笑いを誘った後、「これまでに調べた脆弱性」と題して具体例3つの紹介が成されました。

  • Content-Tyoe無視によるXSS(IE)
  • UTF-7によるJSON Hijacking(IE)
  • E4X + Web Workers = データ漏えい(Firefox)

以下、ひとつずつ見てゆきたいと思います。

Content-Tyoe無視によるXSS(IE)

IE8までのセキュリティ設定には「拡張子ではなく、内容によってファイルを開く」があり、デフォルトで有効(msdn.microsoft.com)になっています。このためサーバー側で適切なMIMEを設定していても、コンテンツの中身によってはHTMLと解釈されXSSが発生する可能性があり、セキュリティ上のリスクとなっていることは古くから知られた事象です。

なお、最新のIE9ではtext/plainなコンテンツをMIMEスニッフィングしなくなっています(blogs.msdn.com)

ユーザーの防御策はこの設定を「無効にする」に変更すること、サーバー側(サイト運営者)の対策は動的コンテンツのレスポンスヘッダに X-Content-Type-Options: nosniff を付けることですね。

UTF-7によるJSON Hijacking(IE)

IE7まではレスポンスヘッダで指定した文字コードより、script要素のcharset属性に指定した方を優先する仕様により情報漏えいが起こりうるというもの。

HTMLで文字符号化方法が複数の方法で指定されている場合の優先順位はHTML4.01の仕様で定められており(www.w3.org)The charset attribute set on an element that designates an external resource.はもっとも優先順位が低いのですが、IE7以下ではHTTPヘッダよりも優先されてしまうようなのです。わけがわからないよ。

手元の環境で試してみたところ、Windows XP + IE7ではXSSが再現したのですが、Wondows 7 + IE8の互換モードでは発動しませんでした。本物のIE7以下でないとダメなのでしょうか。

E4X + Web Workers = データ漏えい(Firefox)

Firefoxでは、古くからE4X(developer.mozilla.org)を実装しており、一見ただのHTMLやXML断片に見える次のような文字列がJavaScriptとしても認識されます。

<p>{foo(<em>test</em>)}</p>

このため "{foo(" と ")}" のように、対象サイトの複数箇所に文字列を挿入することが可能な場合、罠ページにscript要素を書いて対象コンテンツのHTML文字列をJavaScriptとして読み取ることでデータの抜き取りが可能となっていました[1]。その対策として、Firefox 3.5からは先のコードのように文字列がXMLリテラルしかない場合はJavaScriptとして扱わないようになったようです。

一方、Web Workersでは、importScripts()メソッド(www.w3.org)を使うことで別ドメインのスクリプトが実行可能ですが、この機能を使ったときはXMLリテラルのみの場合でもJavaScriptが動作するようになっていたため(Firefox3.6.6まで)、両者の技術を組み合わせることで外部サイトのデータを取得することが可能だった、というもののようです。

  • [1]なお、XML宣言や文書型宣言があると読み取れません。つまりvalidなHTMLとなっていればとくに問題なかったものと思われます。