機密情報を含むJSONには X-Content-Type-Options: nosniff をつけるべき
WebアプリケーションにおいてJSONを用いてブラウザ - サーバ間でデータのやり取りを行うことはもはや普通のことですが、このときJSON内に第三者に漏れては困る機密情報が含まれる場合は、必ず X-Content-Type-Options: nosniff レスポンスヘッダをつけるようにしましょう(むしろ機密情報かどうかに関わらず、全てのコンテンツにつけるほうがよい。関連:X-Content-Type-Options: nosniff つかわないやつは死ねばいいのに! - 葉っぱ日記)。
例えば、機密情報を含む以下のようなJSON配列を返すリソース(http://example.jp/target.json)があったとします。
[ "secret", "data", "is", "here" ]
攻撃者は罠ページを作成し、以下のようにJSON配列をvbscriptとして読み込みます。もちろん、JSONをvbscriptとして実行はできずエラーが発生するので、エラーハンドラも設定しておきます。
<!-- 攻撃者の用意した罠ページ --> <script> window.onerror = function( e ){ alert(e); }; </script> <script src="http://example.jp/target.json" language="vbscript"></script>
被害者がこの攻撃者の用意した罠ページを訪れたときには、JSON配列がVBScriptとして読み込まれ、実行時エラーが発生します。
エラーハンドラには、VBScriptエンジンの生成したエラーメッセージが渡されますが、そこにはJSON配列内の文字列がそのまま含まれますので、攻撃者はJavaScriptから自由にそれらの機密情報にアクセス可能となります。
この脆弱性は、昨年私とmasa141421356さんとで発見し、Microsoftへ連絡しました。無事、今月リリースされた マイクロソフト セキュリティ情報 MS13-037 - 緊急 : Internet Explorer 用の累積的なセキュリティ更新プログラム (2829530)にて「JSON 配列の情報漏えいの脆弱性 - CVE-2013-1297」ということで修正へと至ったのですが、実際にはMS13-037にてこの問題が修正されるのはInternet Explorer 6、7、8だけであり、Internet Explorer 9および10については依然として上記の方法でリモートのJSON配列を攻撃者は読み取り可能なままです*1。
Internet Explorer 9、10に対しては、JSON配列の生成において X-Content-Type-Options: nosniff レスポンスヘッダを付与することで攻撃を防ぐことができます。 X-Content-Type-Options: nosniff レスポンスヘッダが付与されたコンテンツを<script>などで読み込む際には、Internet Explorer 9、10ではContent-Typeが厳密に確認され、VBScriptを示すContent-Typeが付与されていないリソースをVBScriptとして読み込むといったことができなくなるためです。
ちなみに、IE6-8の場合であっても同一オリジン上に配置されるJSON配列に関しては、MS13-037適用後も上記のvbscriptエラーを利用した方法でJSON配列の内容を読み取ることができます。
なお、CVE-2013-1297についてMS13-037ではIE9、10が修正されておらず X-Content-Type-Options による保護が必要となる点については、Microsoft に問い合わせたところ仕様に基づく動作との回答を得ています。
■ まとめ
- リソースが機密情報を含む場合はもちろん、そうでない場合にも全てのリソースに対して X-Content-Type-Options: nosniff をつけるべきでしょう。
- MS13-037ではCVE-2013-1297が修正されるのはIE6-8のみである。
■補足
ブコメやTwitterでの反応をもとに補足編も書きました。
*1:National Vulnerability Database (NVD) National Vulnerability Database (CVE-2013-1297)などでは対象としてIE9、10は書かれていませんが。