機密情報を含む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として読み込みます。もちろん、JSONvbscriptとして実行はできずエラーが発生するので、エラーハンドラも設定しておきます。

<!-- 攻撃者の用意した罠ページ -->
<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は書かれていませんが。