検索
連載

知っていれば恐くない、XMLHttpRequestによるXSSへの対応方法HTML5時代の「新しいセキュリティ・エチケット」(3)(2/2 ページ)

“新しいXSS”は知識こそが対策の第一歩。基本の対策を行うことが重要です。XMLHttpRequestによるXSSも例外ではありません。

Share
Tweet
LINE
Hatena
前のページへ |       

XHRによってやり取りされるデータによるXSS

 皆さんご存じの通り、Internet Explorer(以下、IE)ではContent-Typeに従わずにコンテンツをHTML扱いすることがありますので、XHRでやり取りされるデータを直接IEで開いた場合にXSSが発生することがあります。

【関連記事】

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

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

http://www.atmarkit.co.jp/ait/articles/0903/30/news118.html


 例えば、XHRでJSONをやり取りしているWebアプリケーションにおいて、攻撃者がJSON内にHTML断片を意味する文字列を挿入可能であったとします。

HTTP/1.1 200 OK

Content-Type: application/json; charset=utf-8


{ "msg" : "<script>alert(1)></script>" }


 このJSONをhttp://example.jp/sample.json/a.htmlのように、URLの後ろに「/a.html」を付け足してIEで開くと、コンテンツがJSONではなくHTMLとして解釈され、JavaScriptが動作してしまいます。


コンテンツがHTMLとして解釈され、JavaScriptとして動作してしまう例

 JSONであれば、文字列内の「<」「>」などを「\u003c」「\u003e」のようにエスケープすることもできますが、XHRでやり取りしているデータがJSONではなく、CSVやプレーンテキストの場合は、文字列をエスケープすることはできません。

 このようなXHRでやり取りされるデータを使ったXSSを防ぐには、(1) レスポンスヘッダーに「X-Content-Type-Options: nosniff」を付与し、(2)XHRからのリクエストにのみ応答する、の両方の方法を採る必要があります。

(1)レスポンスヘッダーに「X-Content-Type-Options: nosniff」を付与

 IE8以降では、コンテンツにレスポンスヘッダーとして「X-Content-Type-Options: nosniff」をつけることで、リソースのContent-Typeを無視することがなくなり、HTMLではないものをHTML扱いしてしまうことによるXSSを防ぐことができます。

HTTP/1.1 200 OK

Content-Type: application/json; charset=utf-8

X-Content-Type-Options: nosniff


{ "msg" : "<script>alert(1)</script>" }


 このように、リクエストヘッダーに「X-Content-Type-Options: nosniff」を含むコンテンツを、IE8以降で開いた場合には、Content-Typeがtext/htmlではないためHTML扱いされることはなくなり、XSSが発生することもありません。

 HTMLではないものをHTML扱いしなくなるだけではなく、例えばHTML(text/html)やJSON(application/json)のようなContent-Typeを持つリソースを<script src>で指定した場合にJavaScriptとして解釈することもなくなるため、そのような手法による情報漏えいを未然に防ぐことにもつながります。

 X-Content-Type-Optionsヘッダーは大きな副作用もなく、付与するだけで安全性を高めることができますので、動的に生成されるコンテンツ全てに付けておくことを強く推奨します。

 ただし、X-Content-Type-OptionsレスポンスヘッダーはIE8以降で有効なものであり、IE6およびIE7では対応していないため、IE6およびIE7を使用するユーザーに対してもXSSの保護を提供するのであれば、次に示す「XHRからのリクエストのみ応答する」という対策も併せて必要となります。

(2)XHRからのリクエストのみ応答する

 XHRでやり取りされるデータを、XHRからのリクエストの時のみ応答し、ブラウザーから直接開かれた場合には応答しないようにすることで、Content-Typeを無視して発生するXSSを防ぐことができます。

 リクエストがXHRからであることを明示するために、XHRではリクエスト時にカスタムヘッダーを付与します。

var xhr = new XMLHttpRequest();
xhr.open( "GET", "http://example.jp/sample.json", true );
xhr.onreadystatechange = function(){
    ...
};
xhr.setRequestHeader( "X-Requested-With", "XMLHttpRequest" );
xhr.send();

 このとき、実際に送信されるリクエストは以下のようになります。

GET http://example.jp/sample.json HTTP/1.1

Host: example.jp

X-Requested-With: XMLHttpRequest

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1)

Connection: keep-alive


 サーバー側では、リクエストヘッダーに「X-Requested-With: XMLHttpRequest」というカスタムヘッダーが含まれていることを確認することで、ブラウザーで直接コンテンツを開いたのではなく、XHR経由でのリクエストであることを確認できます。XHRの場合にのみ正規のJSONを応答し、そうでない場合には403や500などの応答を返すことで、ブラウザーで直接コンテンツを閲覧することを防ぐことができます。

 なお、jQueryやprototype.jsなどのJavaScriptライブラリでは、自動的に上記のリクエストヘッダーを付与してくれます。


 このように、XHRを使ってのデータをやり取りする周辺では、XSSが発生しやすくなります。まとめると、以下の2点がポイントになります。

  • 「X-Content-Type-Options: nosniff」ヘッダーを全ての動的生成されるコンテンツに付与する
  • XHRでやり取りするデータは、カスタムのリクエストヘッダーを付けることによりXHRでのみ応答するようにする

 次回は、前回および今回の記事でも少し触れた「オープンリダイレクター」について解説します。

はせがわようすけ プロフィール

http://utf-8.jp/

ネットエージェント株式会社 エバンジェリスト、株式会社セキュアスカイ・テクノロジー 技術顧問。Internet Explorer、Mozilla FirefoxをはじめWebアプリケーションに関する多数の脆弱性を発見。Black Hat Japan 2008、韓国POC 2008、2010他講演多数。


Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       

Security & Trust 記事ランキング

  1. 2025年、LLMの脆弱性が明確になるなど、セキュリティとクラウドに関する8つの変化
  2. Google Cloud、2025年のサイバーセキュリティ予測を発表 AIがサイバー攻撃にもたらす影響とは?
  3. 「SMSは認証に使わないで」 米CISA、モバイル通信を保護する8つのベストプラクティスを公開
  4. “ゼロトラスト”とトラスト(信頼性)ゼロを分かつものとは――情報セキュリティ啓発アニメ「こうしす!」監督が中小企業目線で語る
  5. 終わらせましょう。複雑過ぎるKubernetes/クラウドネイティブが生む心理的安全性の低下を――無料でクラウドセキュリティの勘所が分かる130ページの電子書籍
  6. 2025年に押さえるべきセキュリティの重要論点をガートナーが発表 新しいリスク、脅威、環境の変化、法規制などの動きを把握する指標に使える
  7. ゼロトラストの理想と現実を立命館大学 上原教授が語る――本当に運用できるか? 最後は“人”を信用できるかどうか
  8. 従業員は「最新のサイバー脅威との戦い」を強いられている セキュリティ教育に不満を持つ理由の1位は?
  9. 3割程度のSaaS事業者が標準的なセキュリティ対策をしていない アシュアードがSaaS事業者を調査
  10. 「DX推進」がサイバー攻撃を増加させている? Akamaiがセキュリティレポートを公開
ページトップに戻る