web-dev-qa-db-ja.com

ブラウザクライアントが同じAPIにアクセスする場合、ネイティブクライアントのCSRF検証を安全に無効にするにはどうすればよいですか?

ネイティブ(コンソール、モバイルアプリ)とJavaScriptベースのクライアントの両方からアクセスできるAPIエンドポイントがあります。

CSRF AntiForgeryTokenがJavaScript呼び出し中にのみ呼び出されるようにするにはどうすればよいですか?

  1. これは非認証/匿名の方法で行うことができますか?

  2. または、認証トークン内にリストされている資格が、サーバーがCSRFを適用する必要があるかどうかを判別する唯一の方法ですか? (ネイティブvsブラウザーフロー)

  3. ライブラリ自体ではなく、Javascriptクライアントには、リクエストタイプを決定するために信頼できる特定のHTTPヘッダーと対応する値のセットがありますか?

  4. APIサービス(APIController)を別のDNS名を持つ別のWebサーバーに分離することで、同一生成元ポリシー(SOP)を使用して、JavaScriptクライアントに、上記のシナリオ3では省略されるヘッダーを効果的に適用させることができます?

1

ランダムな順序でいくつかのオプションがあります。

1.異なる認証スキーム

Webブラウザーは、CookieのセッションIDによって頻繁に認証されます。多くのネイティブアプリは、リクエストヘッダー(Authorizationヘッダーまたはその他のカスタムヘッダーキー)に直接認証トークンを添付します。 CSRFは通常、認証でCookieが使用される場合にのみ問題になります。その結果、アプリケーションがCSRFトークンをチェックするのは、ユーザーがCookie経由で認証された場合のみであり、ネイティブアプリがCookieを使用して自分自身を識別しない場合は、問題ありません。

2.クライアント側の証明書

これはおそらく問題にはなりませんが、クライアント側の証明書を介してクライアントの識別を有効にすると(そしてそれを適切に行うと)、会話の反対側の人がブラウザではなくアプリであり、無効にすることができます。 CSRF検証。

3.カスタムヘッダー

1つの潜在的な戦略は、ネイティブアプリからのリクエストにカスタムヘッダーを含め、CSRF保護がある場合はそれを無効にすることです。これはおそらく安全な戦略です。ここでさらに読む:

カスタムヘッダーによるCSRF保護(および検証トークンなし)

4.匿名のリクエスト

これを行うことは匿名の方法です。 some程度(別名、これは100%該当しない)までCSRF攻撃の要点はすべて引き継ぐため、匿名リクエストはCSRF保護を必要としませんユーザーのセッション。ユーザーが匿名でログインしていない場合は、とにかく引き継ぐことはあまりありません。クライアントアクションの結果として状態を保存しないログインなしのアプリケーションは、そもそも実際にはCSRF保護を必要としません(ただし、そこでの意味を誤解している可能性があります)。

5.個別のエンドポイント

これが本当に重要なことだと思います。 2つの異なる方法で2つの異なるクライアントにサービスを提供するエンドポイントがある場合、問題は、CSRFチェックを無効にしたエンドポイントと有効にしたエンドポイントの2つのエンドポイントが必要になることだと思います。もちろん、これが実際に機能するのは、2つのエンドポイントが異なる方法で認証されている場合だけです。これは、実際には項目1に戻るだけです。ネイティブ(CSRFが無効になっている)とWeb(CSRFが有効になっている)の2つのエンドポイントがあり、どちらも認証に同じCookieを受け入れる場合、攻撃者はCSRF攻撃を実行できますWebと同じCookieを受け入れます。

理想的には、あなたが2つの別々のエンドポイントを持っているべきであると思います。 2つがほぼ同じアクションを実行する場合でも、常にシステムを構築して、同じ基本コードを使用して両方のAPI呼び出しを実行できるようにすることができますが、それらは別々のエンドポイントと別々の認証ロジックを持っています。もちろん、もう1つのオプションは、両方のシステムでまったく同じように動作する、両方のシステム用の1つのエンドポイントを用意することです。 2つの異なるシステムで異なる動作をする1つのエンドポイントを持つことは、おそらくトラブルに巻き込まれる最も簡単な方法です。

私はあなたの質問を逐一ぶつけていませんでしたが、これらは事実上すべての選択肢であると信じています。

1
Conor Mancone