web-dev-qa-db-ja.com

これは、OAuthトークンでCookieを保護するために機能しますか?

私は現在、OAuth 2.0認証方式を設定して、いくつかのステートレスを保護しようとしていますREST webservices。これらのサービスは機密情報を扱い、OAuthサポートは必須です。


問題は、クライアントアプリケーションがクライアント側(Angular/Javascript)で100%であり、ユーザーセッションがまったくないため、クライアントでトークンを処理する方法に苦労しています-攻撃者に公開せずにサイド。



計画は次のようなことをすることです:

  1. ユーザー/パスワードの付与を使用して、IdentityServerからトークンを取得します(クライアントアプリケーションは私たちのものであり、client_secretはありません)
  2. トークンをクッキーに保存する
  3. リクエストを行うときは、Cookieからトークンを取得し、それを使用してリクエストに署名します
  4. トークンの有効期限が切れたら、refresh_tokenを使用して新しいトークンを取得します


リクエストを送信するために、次のいずれかを実行できると考えました。

  • トークンに署名する代わりに、認証としてHttpOnly Cookieを送信します
  • AngularのXSRF-TOKEN Cookieを使用します。つまり、Cookieはドメインで実行されているJavascriptのみにアクセスできるようにする必要があります(ただし、XSS攻撃にさらされたままになっていると思いますが?)


Cookieはすべて安全に設定され、HTTPS経由で送信されます。ただし、トークンはプレーンテキストとして保存されるため、これは依然として安全ではないようです。 refresh_tokenもCookieに含まれます。 (私はローカルストレージも検討しましたが、何かを見落とさない限り、安全だとは思われません...)



oauthトークンをクライアント側に保存するより安全な方法はありますか?
または、これは許容できるセキュリティですか?ここで何が欠けていますか?



参照

Angular XSRF保護: https://docs.angularjs.org/api/ng/service/ $ http#cross-site-request-forgery-xsrf-protection

5
lv.

あなたは正しいことを心配していません

クライアントにある情報を保護していますか?

情報を保護するために、情報がクライアント(ブラウザなど)に届いたら、何もする必要はありません。アクセストークンをCookie、Webページの非表示フィールド、HTML5ローカルキャッシュに保存するか、ページの中央に直接表示しても、何も変更されません(ショルダーサーフィンを除く...)。

クライアントでアクセストークンを心配するのは、メモ帳を開いて電子メールのパスワードを書き込んだ後、攻撃者がリモートの場所からその情報を盗む可能性があることを心配するようなものです。それは起こりません。お使いのコンピュータがすでに危険にさらされていないが、この時点ですでに失っている場合を除きます。

心配することは理にかなっていますか?

通常、送信中の情報は脆弱です。 OAuth2(暗黙的フロー)の場合、アクセストークンは2つの場所で転送されます。

  • 認可サーバーからブラウザへ
  • ブラウザからリソースサーバーへ

転送中の情報の保護は、どこでもTLSを使用するのと同じくらい簡単です。 OAuth2を使用していて、プロトコルで必要とされているため、すでに実行しているはずです。

さて本当の問題

OAuth2を使用する予定の方法は、おそらくそれを使用する必要がある方法ではありません。

おそらくOAuth2を誤用する理由を理解するには、フローについて知る必要があります。 OAuth2は4つの承認フローを定義します

  • 承認コード(良いものだけですが...読み続けてください)
  • 暗黙的(誤った安心感)
  • リソース所有者のパスワード認証情報(恐ろしい考え)
  • クライアント資格情報(お客様のケースには適用されません)

JavaScriptクライアントを使用しているため、機能する唯一のフローは暗黙的なフローであり、問​​題が発生します。

暗黙的なフローの問題

たくさんありますが、最も重要なものについて話しましょう。 アクセストークンは特定のクライアントにバインドされていません!仕様セクション10.16より:

暗黙的なフローを使用するパブリッククライアントの場合、この仕様では、クライアントがアクセストークンの発行先のクライアントを決定する方法は提供されません。

これにより、攻撃者がリソースの所有者になりすまして、リソースサーバーにアクセスできるようになります。セクション10.16を読み続けましょう。

リソース所有者は、攻撃者の悪意のあるクライアントにアクセストークンを付与することにより、リソースへのアクセスを喜んで委任する可能性があります。これは、フィッシングまたはその他の口実による可能性があります。攻撃者は他のメカニズムを介してトークンを盗むこともできます。攻撃者は、正当なパブリッククライアントにアクセストークンを提供することにより、リソース所有者になりすまそうとする可能性があります。

暗黙的なフロー(response_type = token)では、攻撃者は認証サーバーからの応答でトークンを簡単に切り替えることができ、実際のアクセストークンを以前に攻撃者に発行されたトークンに置き換えます。

バックチャネルでアクセストークンを渡してクライアントのユーザーを特定することに依存しているネイティブアプリケーションと通信するサーバーも、同様に、攻撃者が任意の盗んだアクセストークンを挿入できる危険なアプリケーションを作成することで危険にさらされる可能性があります。

リソースの所有者のみがリソースの有効なアクセストークンを提示できると想定しているパブリッククライアントは、このタイプの攻撃に対して脆弱です。

その最初の攻撃は実際には攻撃でもなく、暗黙のフローの単なる「欠陥」です...

次の攻撃

今大きなトラブルを開始します。 OAuth2暗黙的フローを、提供することを意図していない委任されたエンドユーザー認証の形式として使用しようとしているようです。仕様セクション10.16に戻る

クライアントに対するリソース所有者の認証は、この仕様の範囲外です。承認プロセスをクライアントへの委任されたエンドユーザー認証の形式として使用する仕様(たとえば、サードパーティのサインインサービス)は、クライアントがアクセスかどうかを判断できるようにする追加のセキュリティメカニズムなしに暗黙のフローを使用してはなりません(MUST NOT)。トークンはその使用のために発行されました(例:アクセストークンを制限するアクセストークン)。

この時点では、ほとんどの場合ゲームオーバーです。

その攻撃を仕掛ける方法は?

とても簡単です。あなたのRESTサービスには、facebookからのアクセストークンが必要でした。攻撃者が実行する必要があるのは、stackoverflowなどのサービスをホストし、facebookからのアクセストークンを要求することだけです。facebookにstackoverflowへのアクセストークン。stackoverflow(攻撃者)は、RESTサービスであなたになりすますことができます。

アクセストークンが特定のクライアントにバインドされていないためです。

解決策

暗黙的なフローを使用せず、代わりに認証コードフローを使用してください。つまり、100%クライアント側のアプリが100%クライアント側のアプリである必要はなくなります。

Angularjsクライアントをユーザーに提供しているサーバーを使用してOAuth2フローを処理しないのはなぜですか?

リファレンス: http://tools.ietf.org/html/rfc6749

3
Gudradain