【3/18〜】Amazon、VMwareが語る『クラウドの未来』 スラッシュドット    はてなブックマーク  Yahoo!ブックマークに登録  印刷
教科書に載らないWebアプリケーションセキュリティ

第2回 [無視できない]IEのContent-Type無視

はせがわようすけ
ネットエージェント株式会社

2009/3/30

XSSにCSRFにSQLインジェクションにディレクトリトラバーサル……Webアプリケーションのプログラマが知っておくべき脆弱性はいっぱいあります。そこで本連載では、そのようなメジャーなもの“以外”も掘り下げていきます(編集部)

icon 無視できないIEの「Content-Type無視」問題

- PR -

 皆さんこんにちは、はせがわようすけです。

 第2回では、Internet Explorer(以下、IE)の仕様でも特に悪名高い「Content-Type無視」について説明します。

 IEのContent-Type無視問題は非常に複雑で、私自身も完全に説明できる自信はないのですが、それでもセキュアなWebアプリケーションを開発するうえで避けては通れない問題ですので、取り上げることにしました。もし記事内に間違いなどを見つけた場合は、ぜひご指摘いただけると幸いです。

 なお、本稿では特に明記していない限り、IE6およびIE7を対象としています。

Content-Type無視によるXSS

 IEのContent-Type無視問題は、Webアプリケーションの開発や検査にかかわる方であれば一度は耳にしたことがあると思います。

 例えば、以下のような「テキストファイル」をIEで開いたとします。

HTTP/1.1 200 OK
Content-Type: text/plain

これはテキストファイルです。
<script>alert("xss");</script>

 この場合、IEは“text/plain”と指定されたContent-Typeヘッダに従わず、コンテンツ内に含まれる内容から「HTML」であると判断して、そこに含まれるスクリプトを実行してしまいます。

 例えば、Wikiなどのプレーンテキストを表示するような機能を持つWebアプリケーションに上記のファイルをアップロードすると、攻撃者によるクロスサイトスクリプティング(XSS)攻撃が可能となってしまいます。これは、HTMLではないコンテンツであるにもかかわらず、IEが「HTMLである」と判断してしまうために発生する問題です。本質的にはWebブラウザ側(IE)で修正されるべき問題なのですが、これも第1回と同じように、互換上の問題から、なかなか対応が進まないようです。

 以下、IEがコンテンツを最終的にどのような種類のドキュメントとして扱うかを「ファイルタイプ」と書くことにします。「IEではContent-Typeやコンテンツの内容を基にファイルタイプを決定している」と考える方がスムーズに理解できるからです。

 さて、IEがContent-Typeだけでなく、ファイルタイプを決定するためにコンテンツの内容をスキャンする動作は「Content sniffing」と呼ばれており、Content-Typeで指定された値やコンテンツに含まれる内容に応じて複雑に変化します。

 Content sniffing自体に関する詳細な説明はここでは省きますが、例えば「Mime Signatures - Web Security Research at Berkeley」および「Secure Content Sniffing for Web Browsers or How to Stop Papers from Reviewing Themselves」という資料では、IEに限らずさまざまなWebブラウザがどのように内容をスキャンし、ファイルタイプを決定しているのかを詳しく説明しています。

 これまでも経験則として「text/plainおよびimage/bmpの動的生成は避ける」といったことが行われてきたと思います。

 このような、Content sniffingによってファイルタイプがHTMLと判断されてXSSが発生することを防ぐには、

  • IE側では「拡張子ではなく、内容によってファイルを開くこと」を「無効にする」に設定する
  • サーバ側のレスポンスヘッダに X-Content-Type-Options: nosniff を追加する(IE8向け)

という対策を行い、Content sniffingを無効にします。

IEのセキュリティ設定

ファイルタイプをどのように判断するのか

 前記のような方法でContent sniffingの設定を変更できますが、Content sniffingはコンテンツの処理方法を決定するための要因の1つにすぎず、Content sniffingが無効になっている場合でも、HTMLではないものがHTMLと判断されXSSを引き起こす場合があります。

 IEがコンテンツの処理方法を決定するための要因としては、少なくとも以下の3種類が使われています。

  • サーバのレスポンスヘッダで指定されたContent-Type
  • コンテンツ自身の中身(Content sniffing)
  • URL

 IEは、これら3種類の情報と、レジストリ(HKCR\Mime\Database\Content Type)に登録されている情報によってファイルタイプを決定していると考えられます。

 レジストリ(HKCR\Mime\Database\Content Type)には、IEが扱うことのできるContent-Typeの一覧が格納されており、サーバからのレスポンスヘッダによって返されたContent-Typeが、レジストリに登録されているかどうかでIEの動作は大きく変わります。

レジストリ

●レジストリに登録されている場合

 サーバの指定したContent-Typeがレジストリ(HKCR\Mime\Database\Content Type)に登録されている場合は、その登録内容に基づき以下のように処理されます。

・IE以外のアプリケーションが処理する場合

PDFのように外部プラグインを呼び出すか、プラグインが見つからない場合はダウンロードダイアログが表示されます。

・Content sniffingが有効な場合

前述のとおり、Content sniffingに基づきファイルタイプが決定されます。

・Content sniffing が無効な場合

サーバ側で指定されたContent-Typeに従って、IE自身がそのコンテンツを処理します。

●レジストリに登録されていない場合

 サーバの指定したContent-Typeがレジストリ(HKCR\Mime\Database\Content Type)に登録されていない場合は、IEは以下のようにファイルタイプを決定します。ここで、「URL拡張子」はURL中のパス名に含まれる拡張子部分を、「QUERY_STRING」はURL中の?以降を指すものとします。例えば、URLが「http://example.com/search.cgi?q=text」であった場合、URL拡張子は“.cgi”を、QUERY_STRINGは“q=text”を示します。

・URL拡張子が“.exe”または“.cgi”であった場合

QUERY_STRINGの末尾部分の“.xxx”の部分が拡張子として使われ、それに基づくファイルタイプが選択されます。例えば、URLが“http://example.com/search.cgi?q=abcd.html”であった場合、拡張子は“.html”となり、ファイルタイプとしてはHTMLが選択されます。

ファイルタイプに対応するハンドラとして外部プラグインが登録されている場合は、該当するプラグインが呼び出されます。選ばれたファイルタイプがIE自身で処理できず、外部プラグインの登録もない場合は、ダウンロードダイアログが表示されます。

ファイルタイプとして“.txt”などが選択された場合には、Content sniffingが無効に設定されていてもContent sniffingが働き、これによりファイルタイプが決定されます。

QUERY_STRINGに拡張子に該当する文字列が含まれない場合は、後述の「URL拡張子が“.exe”および“.cgi”以外の場合」のように処理されます。

・URL拡張子が“.exe”および“.cgi”以外の場合

URL拡張子がそのままファイルタイプの決定に使われます。例えば、URLが“http://example.com/search.pl?q=abcd.html”であった場合、拡張子は“.pl”となり、ファイルタイプとしては“.pl”が選択され、それに応じたハンドラがレジストリから検索されます。

ファイルタイプに対応するハンドラとして外部プラグインが登録されている場合は、該当するプラグインが呼び出されます。選ばれたファイルタイプがIE自身で処理できず、外部プラグインの登録もない場合は、ダウンロードダイアログが表示されます。

また、例えばURLが“http://example.com/search.pl/a.txt?q=abcd”であった場合など、ファイルタイプとして“.txt”などが選択された場合には、Content sniffingが無効に設定されていてもContent sniffingが働き、これによりファイルタイプが決定されます(大抵のCGIプログラムであれば、余分なPATH_INFOを付与しても動作します)。

 
1/2

Index
[無視できない]IEのContent-Type無視
Page1
無視できないIEの「Content-Type無視」問題
Content-Type無視によるXSS
ファイルタイプをどのように判断するのか
  Page2
ファイルタイプ決定の例
Webアプリケーション側の対策

教科書に載らないWebアプリケーションセキュリティ

 Coding Edgeお勧め記事
いまさらアルゴリズムを学ぶ意味
コーディングに役立つ! アルゴリズムの基本(1)
 コンピュータに「3の倍数と3の付く数字」を判断させるにはどうしたらいいか。発想力を鍛えよう
Zope 3の魅力に迫る
Zope 3とは何ぞや?(1)
 Pythonで書かれたWebアプリケーションフレームワーク「Zope 3」。ほかのソフトウェアとは一体何が違っているのか?
貧弱環境プログラミングのススメ
柴田 淳のコーディング天国
 高性能なIT機器に囲まれた環境でコンピュータの動作原理に触れることは可能だろうか。貧弱なPC上にビットマップの直線をどうやって引く?
Haskellプログラミングの楽しみ方
のんびりHaskell(1)
 関数型言語に分類されるHaskell。C言語などの手続き型言語とまったく異なるプログラミングの世界に踏み出してみよう
ちょっと変わったLisp入門
Gaucheでメタプログラミング(1)
 Lispの一種であるScheme。いくつかある処理系の中でも気軽にスクリプトを書けるGaucheでLispの世界を体験してみよう
  Coding Edgeフォーラムフィード  2.01.00.91

Coding Edge フォーラム 新着記事

@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

RSSフィード

スキルアップ/キャリアアップ(JOB@IT)

お勧め求人情報

キャリアアップ 〜JOB@IT
@IT Special -PR-
  TomcatやJBossなどAPサーバ環境に関する
情報を集約! “業務”用APサーバ大百科

New!
  一気に解説! 最新のクラスタストレージ
「RAIDを超えたストレージ基準」……など

New!
  クラウド的ユーザー体験の変化は脅威か?
仮想化技術を使いこなす運用管理術を紹介

New!

  上司や部下、部署内メンバーとの情報共有
を“ガラッ”と変えるコラボツールとは?

New!
  おばかアプリ選手権、第4弾開催中!!
ムダにカッコよくてくだらない作品求ム!

  社内ファイルサーバを“クラウド”に統合
VPN直結「クラウド型ストレージ」を紹介

  Twitterのアカウントはなぜ突破された?
メールによる新手の攻撃手法とその対策

  もう仮想化のお試しフェイズは終わりだ!
Hyper-V 2.0が基幹システムも仮想化

  美人!? まあまあ? 気になる いやし系!!
PV急増で「美人時計」がとった手段とは?

  クライアント企業から求められる人材
⇒IT技術と経営戦略を併せ持つ「戦略家」

  .NET編集長が実践する「技術情報検索術」
サンプル・コードを簡単に探す“技”は?

  業務効率と情報セキュリティ対策を両立!
手間なく確実に機密情報を守る方法とは?

  進化を続ける富士通ストレージETERNUS DX
製品開発者の自信を裏付けるものとは何か

  運用管理の課題を“2つの観点”から分析
ユーザー満足度の高い「仮想環境」とは?

  【CTC事例】約30の基幹システムを統合!
膨大なバッジジョブを制御した方法は?

  仮想化すればコストは削減できるか?
仮想化に必要な「3つの視点」を解説する

  その数、なんと400台以上! グループ内
サーバの「統合管理」によるメリットは?