web-dev-qa-db-ja.com

JSONセキュリティのベストプラクティス?

JSON vs XML の問題を調査しているときに、 この質問 に出会いました。ここで、JSONを好む理由の1つは、Javascriptでの変換の容易さ、つまりeval()によるものとしてリストされました。今、これはセキュリティの観点から潜在的に問題があるとしてすぐに私を驚かせました。

そこで、私はJSONのセキュリティの側面についての研究を始め、このブログ投稿全体で JSONは人々が考えるほど安全ではない について調査を始めました。この部分が突き出ました:

更新:JSONを100%適切に実行している場合、オブジェクトは最上位にのみ存在します。配列、文字列、数値などはすべてラップされます。 JavaScriptインタープリターはオブジェクトではなくブロックを見ていると考えるため、JSONオブジェクトはeval()に失敗します。これは、これらの攻撃からの保護に大いに役立ちますが、予測不可能なURLで安全なデータを保護することは依然として最善です。

OK、それが最初の良いルールです:最上位のJSONオブジェクトは常にオブジェクトであり、配列、数字、文字列であってはなりません。私には良いルールのようですね。

JSONやAJAX関連のセキュリティに関しては、他にやるべきことや避けるべきことはありますか?

上記の引用の最後の部分では、予測不可能なURLについて言及しています。これについて、特にPHPでどのようにそれを行うのか、誰にも詳細がありますか?私はJava PHPよりも、そしてJavaそれは簡単です(全体をマッピングできるという点で)すべてのPHP私がやったことは、単一のURLをPHPスクリプトにマッピングしました。

また、予測不能なURLをどのように使用して、セキュリティを強化しますか?

73
cletus

ブログの主なセキュリティホール(CSRF)は、JSON固有ではありません。代わりにXMLを使用するのと同じくらい大きな穴です。実際、非同期呼び出しがまったくないのと同じくらい悪いです。通常のリンクも同様に脆弱です。

人々がユニークなURLについて話すとき、彼らは一般的に http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement を意味しません。代わりに、リクエストについて何か他のものを一意にする方が一般的です。つまり、FORMポストの値、またはURLパラメーターです。

通常、これにはサーバーサイドのFORMに挿入されたランダムトークンが含まれ、リクエストが行われたときにチェックされます。

配列/オブジェクトの事は私にとってニュースです:

スクリプトタグ:攻撃者はリモートサーバーを指すスクリプトタグを埋め込むことができ、ブラウザーは応答を効果的にeval()しますが、応答を破棄します。JSONはすべて応答であるため、安全です。

その場合、あなたのサイトはJSONを使用する必要はまったくありません。しかし、ええ、攻撃者があなたのサイトにランダムなHTMLを挿入できるなら、あなたは乾杯しています。

18
Chase Seibert

JSON、特にXSRFに対するセキュリティ攻撃が多数あります。

この脆弱性は、Webサービスが認証にCookieを使用し、GET要求への応答で機密データを含むJSON配列で応答する場合に発生します。

攻撃者がサービスnaive-webapp.comにログインしているユーザーを自分のサイト(または埋め込み広告などを介して制御するIFRAMEを組み込んだサイト)にログインさせると、<script> naive-webapp.comへのSRCでタグ付けし、潜在的にユーザーのデータを盗みます。これは、次のようなJavaScript Arrayコンストラクターを持つjavascriptの癖に依存します。

 <script>
   // Overload the Array constructor so we can intercept data
   var stolenArrays = [];
   var RealArray = Array;
   Array = function () {
     var arr = RealArray.apply(arguments);
     stolenArrays.Push(arr);
     return arr;
   }
 </script>
 <!-- even though the attacker can't access the cookies,
   - he can cause the browser to send them to naive-webapp.com -->
 <script src="//naive-webapp.com/..."></script>
 <script>
   // now stolenArrays contains any data from the parsed JSON
 </script>

EcmaScript 5は、[]グローバルオブジェクトと多くの最新のブラウザでArrayを検索するには、この攻撃の影響を受けなくなりました。

ちなみに、Oilは予測不可能なURLについて間違っています。 URLの暗号化された安全なランダム識別子は、リソースを保護する優れた方法です。オイルが示唆するように、アイデンティティベースのセキュリティは万能薬ではありません。 IDの概念を必要としないURLの暗号的に安全な識別子に基づく安全な分散アプリケーションスキームの例については、 http://waterken.sourceforge.net/ を参照してください。

編集:

JSON対XMLを検討する際には、XML固有の攻撃ベクトルにも注意する必要があります。

[〜#〜] xxe [〜#〜] 、XML外部エンティティ攻撃。巧妙に細工されたXMLを使用して、ファイアウォールを介してファイルシステムとネットワークリソースにアクセスします。

<!DOCTYPE root 
[
<!ENTITY foo SYSTEM "file:///c:/winnt/win.ini">
]>
...
<in>&foo;</in>

アプリケーションは、入力(win.iniファイルを含むパラメーター「in」)をWebサービス応答に埋め込みます。

53
Mike Samuel

予測不可能なURLで安全なデータを保護するために、まだbestです。

強調鉱山。なんてナンセンスだ! bestは、適切な認証とその上での暗号化によって安全なデータを保護します。 JSON交換では、既存の認証手法(Cookieを介したセッションなど)およびSSLを引き続き使用できます。

JSONを使用して匿名のサードパーティ(Webサービスなど)にデータをエクスポートする場合、URLを推測しない誰かに頼ること(彼らが効果的に話していること)は妥当なテクニックになります(その場合でも) 。 1つの例は、匿名ユーザーが他のWebサイトからGoogleデータにアクセスするGoogleのさまざまなWebサービスAPIです。ドメインリファラーとAPIキーを使用して、中間者ウェブサイトがGooogleデータを提供できるようにします。

JSONを使用して、直接既知のユーザーエージェントとの間でプライベートデータを送受信する場合は、実際の認証と暗号化を使用します。 Webサービスを提供しようとしている場合、このデータがどうなるか "secure"に大きく依存します。それが単なる公開データであり、誰がそれを読むことができるかを気にしない場合、私は恥ずかしがり屋のURLを作成する意味がわかりません。


編集:それらの意味を示すために、これを考慮してください。銀行がステートメントを取得するためのJSON APIを提供したと想像してください。 http://yourbank.com/json-api/your-name/statementと入力するだけなら、あなたはたぶん喜ばないでしょう。

ただし、JSONリクエストで必要なアカウントの一意の文字列を生成できます。例:http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement

それを推測できる可能性ははるかに低いでしょう。しかし、本当に安全なデータと潜在的な個人情報窃盗犯との間の唯一のバッファであることを本当に望みますか?いや.

3
Oli