web-dev-qa-db-ja.com

JSONPは安全に使用できますか?

JSONPを使用する際に考慮すべきセキュリティ上の問題はありますか?

66
dits59

Update:JSONPは、クロスドメインリクエストを行うための一般的なハックです。最近のブラウザにはクロスオリジンリソース共有があり、IE8 +には同様のXDomainRequestがあります。詳細については、 http://enable-cors.org/ を参照してください。

JSONPは、コールバックを使用できるようにするスクリプトインクルードです。ただし、 クロスサイトリクエストフォージェリ(CSRF) に注意する必要があります。

スクリプトとサーバーを制御している限り、JSONPはスクリプトが含むよりも安全ではありません。ログインしたユーザーに機密データを返すJSONPサービスがない限り。悪意のあるサイトは、サービスにリクエストを送信して(ユーザーがサイトにログインしていることを期待して)データを取得できます。サービスはリクエストのリファラーを確認できますが、フラッシュを使用してリファラーを偽装することは可能です(Chris Moschiniに感謝します)。

このシナリオを想像してください。-ユーザーが自分のインターネットバンキングアカウントにログインします。ユーザーのブラウザにセッションCookieを保存します。このサイトには、ユーザーと彼のアカウントに関する機密情報を含むjsonpサービスがあります。 -他のサイトはユーザーがログインしていることを知りませんが、ユーザーは思い切ってjsonpサービスにアクセスしようとします。ユーザーはセッションCookieを持っているため、ブラウザーは応答を取得し、サイトがAjax投稿を行ってサーバーに機密データを保存することを妨げるものは何もありません。

2012年6月28日更新:CSRF攻撃から保護したい場合は、セキュリティの専門家による詳細なブログ投稿をお読みください: http: //erlend.oftedal.no/blog/?blogid=1

66
gregers

はい、注意する必要がありますが、信頼できるサービスで適切に使用すると、比較的安全です。

私が理解しているとおり、JSONPのセキュリティ問題の概要は次のとおりです。

消費者の観点から:

  • 指定したJSONPコールバックでラップされた予想されるJSONの代わりに、悪意のあるJavaScriptを返さないようにプロバイダーを信頼する必要があります。
  • 同じことは、GoogleアナリティクスなどのサードパーティのJavaScript組み込みアドオンにも当てはまります。
  • サードパーティがアプリケーションで任意のJavaScriptを実行できるという点でXSS攻撃に似ていますが、最初にリクエストを行うことにより、まずそのサードパーティを信頼することを選択する必要があります。

プロバイダーの観点から:

  • クライアントのCookieがリクエストに存在していても、消費者があなたの管理下にあるWebページであると想定してはなりません。 Refererヘッダーを承認済みURLのホワイトリストと照合し、Cookieベースの認証に依存しないでください。
  • CSRF /混乱した代理攻撃に類似しています。
21
tlrobinson

両側にセキュリティ上の問題があります。最も深刻なものは、JSONPを含むサイト用です。

別のドメイン(制御しない)からのを含める場合、そのドメインはいつでもスクリプトを変更できます。彼らはあなたのウェブページのコンテキストであなた自身のジャバスクリプトができることをジャバスクリプトにさせることができます。 JSONPを使用する場合、これを回避する方法はありません。 iframeを使用したクロスドメイン通信を検討する必要があります。これは、優れたEasyDXMライブラリによって最適に実行されます。

JSONPを処理するWebサービスを提供している場合、クロスサイトリクエストフォージェリ(CSRF)から保護する必要があります。これは、Webサービスがログインユーザーに機密情報を返す場所です。ユーザーがあなたのサイトにログインしている場合、他のサイトはJSONPサービスへのGETリクエストを生成でき、あなたのドメインのCookieはリクエストで送信されます-本質的に、ログインしているユーザーを認証します-現在、リモートドメインが応答を取得し、機密データを読み取ることができます!

CSRFから保護する最善の方法は、ナンス(推測が困難でランダムに生成された番号)を生成し、セッションに保存することです。あなたのウェブページのすべてのフォームにこのノンスを出力し、あなたのページのすべてのJSONPリクエストに含めます。サーバーでは、リクエストにノンスが存在し、正しいことを確認します(GET、POSTなど)。他のドメインは、このノンスを推測できず、Cookieにもかかわらず機密情報を取得できません。送信されています。

最後に、別の種類のセキュリティ問題があります。JSONPは、ブラウザでのユーザー認証をサポートしていません。OAuthで可能な種類です。もちろん、サーバーに何らかの種類のアクセストークン(OAuthなど)を取得させて使用することもできます。ただし、ブラウザで完全に認証を行いたい場合は、iFrameとのクロスドメイン通信を使用する必要があります。 OAuth 2.0がそれを行う方法だと思います。あなたのサイトでホストされているページはあなたのサーバーに完全にアクセスできます。EasyDXMをロードし、それを使用してサイトに非表示のiframeを作成し、それを使用して話します。

12

JSONPはJavaScriptとしてクロスドメインを取得するものは何でも実行するだけなので、間違いなく安全ではありません。

ソリューション!解決策!

Iframe(できればサンドボックス化されたもの)を作成し、そこにJSONPをロードします。結果をキャッチし、window.postMessageで渡す

そして、はい、誰かがいつものように最初にこのアイデアを得ました:)

ブログの投稿はもうありませんが、信用のためにここにリンクを保持しています: http://beebole.com/blog/general/sandbox-your-cross-domain-jsonp-to-improve-mashup -security /
編集: ウェイバックマシンリンク

Iframe通信にはwindow.nameハックを使用しましたが、それはIE6と7でした。

4
naugtur