web-dev-qa-db-ja.com

この設定でCSRF保護は、REST APIとoauth2および基本認証SSO認証サーバーでサポートされている必要がありますか?

私は答えを見ました Cookieを使用しない場合でもCSRFは可能ですか? しかし、2つの矛盾する答えがあり、質問自体はそれほど多くの情報を提供しません。

別のドメインで実行されている(独自に作成した)Webクライアントが使用するREST APIを作成しているので、CORSリクエストを実行します。このAPIはoauth2リソースサーバーとして実行されるため、認証ヘッダーで渡されるアクセストークンによってアクセスが制限されます。 Cookieはありません。すべてステートレスです。 https://spring.io/blog/2011/11/30/cross-site-request-forgery-and-oauth2 の記事のアドバイスに従っています

  • SSLを使用します
  • 事前登録されたリダイレクトURIがあります
  • 私たちの唯一の付与タイプは承認コードであり、 https://oauth.net/2/grant-の推奨事項に従って、暗黙の付与タイプの代わりにクライアントシークレットを必要としません(Webクライアントソースはパブリックなので)。タイプ/暗黙/
  • クライアントは、実際のリソースサーバー呼び出しを行うときにヘッダーで認証します
  • アクセストークンの取得は、フォームパラメータ(x-www-form-urlencoded)で1回限りの認証コードを渡すことで行われます。これは通常の方法のようですが、クエリパラメータではないため、ブラウザの履歴にスタックしないでください。
  • クライアントは、認証コードを取得するときに、いくつかの秘密の状態パラメーターも使用します。この場合、クライアントはシークレットに依存せずにコードを交換してアクセストークンを取得するため、ポイントがあるかどうかはわかりません。
  • 実際にアクセストークンを取得するoauth/tokenエンドポイントの場合、許可される唯一のOriginはWebクライアントのドメインです
  • Oauth/authorizeエンドポイントの場合、CORSは許可されません。リダイレクトURIがとにかく私たち自身のドメインのみを指すので、おそらくこれは過度です。

それはその側のほとんどすべてをカバーしていると思います。

現在、IS SSOであると想定され、セッションを持ち、基本認証でアクセス可能な、oauth2認証サーバー自体の形式の別の可能な攻撃ベクトルがあります。ただし、実際に役立つcsrf攻撃で実行できるアクションはないようです。これらのoauthエンドポイントにリクエストを行うことはできますが、結果を読み取ることができる必要があります。これは、CORS構成とリダイレクトURIが事前登録されているという事実によって妨げられます。パスワードを変更したり、電子メールアドレスをリセットしたりするためにPOSTすることはできません。これらすべては、実際にはリソースサーバーとしても公開されます。

何か不足していますか?ここで脆弱性の調査をどのように行いますか?

最初の質問に答えるには、Cookie(セッション)を使用しておらず、ブラウザー内で基本認証を使用していない場合、リソースサーバーにCSRF対策を実装する必要はありません。

Cookieと基本認証ヘッダーは、アクセスするすべてのドメイン名についてブラウザーによって保存され、サイトにリクエストを送信するたびに、保存されたCookieと基本認証ヘッダーがリクエストヘッダーに自動的に追加されます。

アクセストークンを使用しているため、おそらくAuthorization: Bearer <token>、あなたは安全でなければなりません。ご使用のブラウザーはこの種の許可の処理方法を認識していないため、すべての要求にこのヘッダーを手動で追加する必要があります。

リダイレクトURI

OAuth 2.0標準で推奨されている、事前登録されたリダイレクトURIを使用しています。これにより、認証サーバーのみが信頼できるサイトに認証コードsends認証コードを確実に送信します。

リダイレクトURIがHTTPSなどの安全なスキームを使用していることが重要です。そうでないと、MITM攻撃に対して脆弱になります。

アクセストークンの認証コードの交換

認証サーバーからリダイレクトされたときに、サイトはクエリパラメータを通じて認証コードを受信して​​います。ほとんどの場合、認証コードはアクセストークンとすぐに交換され、後で認証コードを取り消す必要があります。

stateパラメータは、CSRF攻撃を防ぐためにここで使用する必要があります。ランダムな値をauthorizeエンドポイントに送信し、認証コードで同じ値を受け取っていることを確認します。 SPAでは、ランダムな値をローカルストレージに保存できます。

SPAでは、これについて心配する必要はありません。ステートフルなサーバー側Webアプリケーション。攻撃者が自分のWebページから認証ページにリダイレクトするとどうなりますか?あなたはあなた自身のSPAに行き着き、そこで攻撃者は続けることができないはずです。

ステートフルなサーバー側アプリケーションでは、この承認を行うことで、実際にアカウントをリンクし、事態が発生する可能性があります。 (もちろん、アプリケーションによって異なります。)

tokenエンドポイントのCORS

まず、CORSはブラウザによってのみチェックされるため、攻撃者がtokenエンドポイントを使用するのを阻止するために、これに依存することはできません。

ここでCORSを回避するために、攻撃者が行う必要があるのは、tokenエンドポイントにリクエストを送信するだけのプロキシエンドポイントを作成することです。

さらに、tokenエンドポイントは、有効な認証コードを受け取った場合にのみ機能します。

authorizeエンドポイントのCORS

通常、ユーザーはauthorizeエンドポイントにリダイレクトし、そこで(サインインして)認証ボタンをクリックし、アプリケーションへのアクセスを許可します。

CORSがなければ、攻撃者は自分のサイトを作成できる可能性があります。攻撃者はXHR/fetchを使用してauthorizeページを取得します。また、ユーザーがauthorizeページに(ステートフルに)サインインしているとすると、ユーザーの同意なしに、承認ボタンをクリックできるようになります。

XHRページを取得するためにfetch/authorizeを使用する必要があるシナリオはありません。したがって、CORSで安全にブロックできます。

認可サーバー

作成時に許可サーバーがステートフルである場合、何かを変更する可能性のあるアクションを実行するときはいつでも、CSRF保護を実装する必要があります。一般的にこれを行うのがベストプラクティスであり、将来パスワード更新機能を追加する場合、CSRFから保護するために必要なコードがすでにあります。

推奨事項

OAuth仕様を理解しているようで、想定どおりのことをしているようです。

  • 明らかな推奨事項は、プリロード(およびHPKP)でHSTSを使用して、MITM攻撃を防ぐことです。
  • 認証コードの有効期間が短く、1度しか使用できないことを確認してください。それらは非常に長い間有効である必要はなく、通常のシナリオでは、付与された直後に使用されます。
  • 最終アクセストークン、更新トークン、認証コードをデータベースに保存しないでください。代わりに、識別子(例:64バイトのランダム)を格納し、署名付きバージョン(例:JWT)を発行します。これにより、攻撃者はアクセストークンを使用できないため、攻撃者がデータベースからアクセストークンを抽出することを防ぎます。
  • OAuthの標準実装を使用してください。独自に実装しないでください。
7
Daniel