OAuth Hijacking leads to account takeover から学ぶ

ソース:

medium.com

脆弱性:OAuth

 

訳:

OAuthとは何ですか?

OAuth は、アプリケーションに「安全な指定アクセス」機能を提供するオープン標準の認証プロトコルまたはフレームワークです。 たとえば、benzac.com が Facebook のパスワードを教えなくても、あなたのプロフィールにアクセスしたり、タイムラインに更新を投稿したりしても問題がないことを Facebook に伝えることができます。 OAuth は認証にも使用できます。 たとえば、ソーシャル サインイン機能 [ GoogleFacebookMicrosoft ] を使用してアプリケーションにログインします。

Google ワン タップ サインインとは何ですか?

Google One Tap は、ユーザーが 1 回のクリックでアカウントを作成したり、Web サイトにログインしたりできる新機能です。 とも呼ばれます YOLO (You Only Login Once)

ログイン ウィジェットはポップアップとして表示され、ユーザーにサインインするか、既存の Google アカウントでサインアップするよう求めます。

 

Google One Tap サインインはどのように機能しますか?

JavaScript ライブラリが Web サイトに含まれています。
HTML または JavaScript を使用して、個人用ボタンの外観と操作性をカスタマイズし、ワンタップで自動サインインおよびサインアウト動作を制御します。

初めてログインするユーザーは、Google アカウントのプロフィール情報を共有することに同意するよう求められます。
同意した後、ユーザーの名前、電子メール、プロフィール写真を含む JSON Web Token (JWT) 資格情報がコールバック ハンドラーを使用して共有されます。

これで、 ID トークンを 使用してプラットフォーム上に新しいアカウントを作成したり、認証されたユーザーがサイトを引き続き使用できるようにしたりできるようになります。

出典: https://www.loginradius.com/blog/identity/google-one-tap-login/

 

サーバー側では、このトークンがアプリケーションに既に登録されている人物のものであるかどうかを確認するために、開発者は ID トークンをどのように処理しますか?

まず、IDトークンPayloadには何が入っているのでしょうか?

 

{
"iss": "https://accounts.google.com",
"azp": "1234987819200.apps.googleusercontent.com",
"aud": "1234987819200.apps.googleusercontent.com",
"sub": "10769150350006150715113082367",
"at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
"hd": "example.com",
"email": "abushadad@example.com",
"email_verified": "true",
"iat": 1353601026,
"exp": 1353604926,
"nonce": "0394852-3190485-2490358"
}

 

iss (issuer): Issuer of the JWT (Google)
sub (subject): Subject of the JWT (the user)
aud (audience): Recipient for which the JWT is intended (The Client)
exp (expiration time): Time after which the JWT expires
iat (issued at time): Time at which the JWT was issued; can be used to determine age of the JWT
jti (JWT ID): Unique identifier; can be used to prevent the JWT from being replayed (allows a token to be used only once)

 

バックエンドでの ID トークンの検証には、いくつかの手順が必要です。

  1. ID トークンが発行者によって適切に署名されていることを確認します。
  2. の値が issID トークン内のクレームは次と等しい https://accounts.google.comまたは accounts.google.com
  3. の値が audID トークンのクレームはアプリのクライアント ID と同じです。
  4. 有効期限 ( expID トークンのクレーム) が渡されていません。
  5. 最後のステップは、このユーザーがアプリケーションにアカウントを持っているかどうかを確認することです。これは、次のいずれかの値を使用して行われます。
    sub主張するか、 email請求
  • email」 値または「 sub」 値がアプリケーション内のアカウントにリンクされている場合、アプリケーション内の認証メカニズムの性質に従って、セッションまたは JWT が応答で返されます。 そうでない場合は、登録機能を呼び出して、「電子メール」の要求に基づいてアカウントを作成します。

 

from google.oauth2 import id_token
from google.auth.transport import requests

try:
  # Specify the CLIENT_ID of the app that accesses the backend:
  idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)

  # ID token is valid. Get the user's Google Account email from the decoded token.
  userid = idinfo['email']
except ValueError:
  # Invalid token
  pass

 

しかし、開発者が何らかの理由でaudience の value をチェックしなかったらどうなるでしょうか?

 

この場合、別のクライアントの ID トークンを使用して、ターゲット アプリケーションにログインしたり、新しいアカウントを作成したりできます。
使用しているアプリケーションを参照するクライアントに固有である必要はなく。
ただし、ID トークンは Google によって署名されており、有効期限を過ぎていない必要があります。

攻撃シナリオ:

攻撃者は、「Google 開発者プラットフォーム」でクライアントを作成し、特定のアカウントを乗っ取るためにオーディエンス値を「チェックしない」などの設定ミスを悪用する目的で、アプリケーションで Google One Tap サインインを設定する可能性があり。
ユーザーが脆弱なアプリケーションに登録し、さらに Google One Tap サインインを通じて攻撃者のアプリケーションにも登録した場合

 

 

ほなほな。