Webセキュリティの小部屋

Twitter のフォローはこちらから Facebook ページはこちら RSSフィードのご登録はこちらから
公開日:2013年7月28日
最終更新日:2020年8月13日

JSON セキュリティ対策

JSON 概要

JSON (JavaScript Object Notation) とは、JavaScript で記述されたデータフォーマットであり、JavaScript で簡単に操作できることが特徴です。

JSON の記述形式は以下のようになります。"名前":"値" の形式となり、値が複数ある場合はカンマでつなぎ、全体を{}(中括弧)で囲みます。

{"Name":"Yamada","Age":10}

JavaScript では以下のように使用します。値がオブジェクトのプロパティとして簡単に扱えることが分かります。
//文字列を JSON に変換
var obj = JSON.parse('{"Name":"Yamada","Age":10}'); 

//コンソールに内容を出力
console.log("Name = " + obj.Name); //Name = Yamada
console.log("Age = " + obj.Age);   //Age = 10

JSON のセキュリティ

JSON のセキュリティを考える場合は、Web サーバーとの通信とブラウザ上での操作について考える必要があります。

Web サーバーとの通信

通常、JSON は XMLHttpRequest を利用した Ajax の通信として利用されますが、XMLHttpRequest はセキュリティ上の理由から JavaScript がある Web サーバーと同じリソースにしか基本的にアクセスできません(同一オリジン)。

しかし、JSONP (JSON with padding) という手法を使用すると、別ドメインの JavaScript を読み込み実行することができるようになります。

JSONP とは

JSONP とは、以下のように JavaScript を記述して外部の JavaScript を読み込んで実行する手法です。

<script type="text/javascript">
  function callback(ret) {
    var obj = JSON.parse(ret);
    alert(obj.Name + ":" + obj.Age);
  }
</script>
<script src="Scripts/jsonp.js"></script>

ここで、jsonp.js は内容は以下のようになります。JavaScript が読み込まれた時に、コールバック関数である callback を呼び出します。
callback('{"Name":"Yamada","Age":10}')

JSONP は外部サイトの JavaScript を読み込むので、相手の Web サイトを信用できなければいけません。最初は問題がなかったのに途中で JavaScript の内容が書き換わり問題を起こした事例もありました。ですので、JSONP の採用は慎重に行うべきでしょう。

なぜここで JSONP を取り上げたかというと、JSON を返す Web サービスを JSONP で呼び出された場合に「JSON ハイジャック」という問題が起きるためです。

JSON ハイジャック

JSONP で JSON を返す Web サービスを呼び出したとしても、ただの JavaScript のデータが <script> 要素内に追加されるだけなので、通常は問題ありません。

ですが、JSON ハイジャックという手法を使用すると、この JSON のデータを読み込む JavaScript が実行でき、攻撃者が JSON データを取得することができてしまいます。

対策方法は以下のようになります。

  • JSONP で Web サービスを呼び出せないようにする
  • JSON を JSON としてブラウザが認識するようにする

JSONP で Web サービスを呼び出せないようにするためには、リクエストヘッダーをチェックします。jQuery や prototype.jp といった JavaScript ライブラリを使用すると、以下のリクエストヘッダーが付与されるのでこれをチェックします。XMLHttpRequest 以外のリクエストはエラーにします。

X-Requested-With: XMLHttpRequest

JSON を JSON としてブラウザが認識するようにするようにするためには、レスポンスヘッダーを以下のようにします。

  • Content-Type を "application/json; charset=utf-8" にする
  • "X-Content-Type-Options: nosniff" ヘッダーを追加する

これで JSON ハイジャックを防ぐことができます。

ブラウザ上での操作

JSON をブラウザ上で JavaScript を使用して操作するには注意が必要です。正しい対応を行わないと、脆弱性が発生してしまいます。

対策のポイントは以下の2つです。

  • eval インジェクション対策
  • クロスサイト・スクリプティング対策

まず、文字列を JSON に変換する方法を見てみましょう。以下の内容なら問題なく JSON に変換することができます。

var obj = eval('({"Name":"Yamada","Age":10})');

ですが、出力値に問題があるような以下の内容では、JavaScript が実行されてしまいます。これを eval インジェクションと呼び対策が必要です。
var obj = eval('({"Name":"Yamada","Age":""+alert(1)+""})');

eval インジェクションを防ぐには、JSON.parse 関数を使用します(Internet Explorer 8以降の場合)。jQuery を使用する場合なら $.parseJSON 関数でも同じことができます。
//両方とも実行時に文法エラーが発生する
var obj = JSON.parse('{"Name":"Yamada","Age":""+alert(1)+""}');
var obj = $.parseJSON('{"Name":"Yamada","Age":""+alert(1)+""}');

また、jQuery で以下のように記述してテキストを追加するのは一見問題ないように思えます。
$("#name").html("Yamada");

ですが、以下のように記述すると JavaScript が実行されてしまいます。
$("#name").html("\<script\>alert(1)\</script\>");

これは <script> タグが HTML エスケープされていないためです。HTML エスケープを行うには以下のように記述します。これで JavaScript は実行されなくなります。
$("#name").text("\<script\>alert(1)\</script\>");

おわりに

JSON のセキュリティ対策は情報源が少ないですが、上記対策を行うことで安全に JSON を使用できるようになります。しかし、対策をそもそもしていない、対策モレがある Web サービスも多いと思うので対策をご検討ください。

また、上記の内容は対策に的を絞っているので対策の背景はあまり記述していません。背景を詳しく知りたい場合は、参考サイトをご確認ください。

参考サイト

参考

Webアプリケーションセキュリティに関する記事は、以下のページにまとまっています。ぜひご確認ください。


スポンサーリンク





カテゴリー:Webアプリケーションセキュリティ対策

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA