MS_OAuthThreatModelRole - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

OAuth 2.0 Threat Model (Role)

概要

OAuth 2.0 Threat Model and Security Considerations
Role に着目した脅威モデル。

  • Client
  • Authorization Server
    • Authorization Endpoint
    • Token Endpoint

Client

Client に対する攻撃

client_secret の入手

概要

client_secret の漏洩により、Authorization Server に対して、
クライアント認証をバイパスしたアクセストークン・リクエストが可能になる。

影響

  • Client 全体への影響

  • アクセストークン・リクエストによる access_token, refresh_token の開示

    • Client Credentials グラント種別によるアクセストークン・リクエスト。

    • リプレイ攻撃によるアクセストークン・リクエスト。

      • code による access_token の取得
      • refresh_token による access_token 取得
  • access_token の漏洩により、
    Resource Owner の、その scope のリソースにアクセス可能になる。

攻撃

リバース・エンジニアリングによって、

  • (難読化したとしても、)ソースコード(リポジトリ)またはバイナリから取得

  • インストール(デプロイ済み Client)から取得

    • web site (web server)
    • device (native application)

対策

  • インストール(デプロイ済み Client)から
    デプロイメント固有の client_secret を取得(ただし、以下を考慮)

    • Client が「Web サーバ」の場合
      システムのセキュリティ対策を実施する。

    • Client が「ネイティブアプリ」の場合
      安全なローカル・ストレージに保存

  • Client 側の要件

    • パブリック・クライアント、脆弱 or 悪意のある Client に公開しない。
    • Client の自動認可を許可しない(ユーザの同意を要求する)。
  • AuthZ 側の要件

    • client_secret 取り消し処理の実装。

補足(結論は「秘密を持たせない」): 本節の対策は
「ネイティブアプリにも client_secret を持たせる(ただし工夫する)」
という前提に立っているが、その後の
OAuth 2.0 for Native Apps(RFC 8252)と
Security BCP(RFC 9700)は、
配布されるアプリは Public Client として client_secret を持たない
という整理に変わった。
代わりに PKCE で code を保護する。
「難読化しても取れる」という本ページの指摘が、そのまま
「なら最初から持たせない」という結論に至った形である。

refresh_token の入手

概要

refresh_token の漏洩により、Authorization Server に対して、
アクセストークン・リクエストが可能になる(クライアント認証にリプレイ攻撃)

影響

  • 単一の Resource Owner への影響

  • アクセストークン・リクエストによる access_token, refresh_token の開示

    • 入手した refresh_token を用いる。

    • クライアント認証に対するリプレイ攻撃を行う
      (若しくは上記「client_secret の入手」で漏洩した client_secret を使用する)。

攻撃

  • Web application から
  • device (native application)
    • ファイルシステムから
    • device を盗難してから
    • device を複製してから

対策

  • Client 側の要件

    • 上記から取得されないようにする。

    • device (native application) の場合、

      • 秘密を安全な記憶域に保管する。
      • デバイスロックを使用する。
  • AuthZ 側の要件

    • 共通

      • refresh_token の scope 制限
      • refresh_token のローテーション
    • Web の場合

      • 強力なクライアント認証を使用
      • 標準的な Web サーバ保護対策
    • device (native application) の場合、

      • ユーザやデバイスを特定できるようにして、
        client_id にトークンをバインド
        ・トークンにデバイス識別子を同梱

      • 以下の取り消し処理を実装する。
        ・refresh_token
        client_secret

補足(ローテーションが必須要件になった): 「refresh_token の
ローテーション」は現在、Public Client では
Security BCP の必須要件である
(ローテーション、または DPoP 等で
送信者に縛るかの二択)。
併せて、古い refresh_token が再提示されたら
そのトークン ファミリ全体を失効させることで、
「盗まれたか否か」を能動的に検知できる。

access_token の入手

概要

単純な、access_token の漏洩は、そのまま、リソースにアクセスが可能になる。

影響

  • 単一の Resource Owner への影響
  • そのスコープのリソースにアクセスが可能になる。

攻撃

上記「refresh_token の入手」と同じ攻撃。

対策

  • Client 側の要件

    • 一時メモリやプライベート・メモリに保持する。
    • その他、上記「refresh_token の入手」と同じ対策。
  • AuthZ 側の要件

    • access_token の scope 制限
    • access_token の有効期間を短くする。

WebView などの組込ブラウザによるフィッシング

概要

OAuth では Client に認証情報を渡さないが、
WebView などの組込ブラウザの場合、
悪意のある Client の場合、Client が認証情報を取得し得る。

影響

ユーザ・アカウントを含めたあらゆる情報が取得され、それが悪用される可能性がある。

攻撃

ブラウザによる、認証情報を中心にした、あらゆる情報のフィッシング

対策

  • Resource Owner 側の要件

    • Client(アプリケーション)の検証
    • 信頼できるシステム・コンポーネント(システム・ブラウザなど)に委任
  • Client 側の要件

    • 信頼できるシステム・コンポーネント(システム・ブラウザなど)に委任
  • AuthZ 側の要件

    • Client タイプの検証(例えば、Google は WebView をブロックしている)

補足(外部ブラウザが標準になった): 「システム・ブラウザに委任」は
その後 OAuth 2.0 for Native Apps(RFC 8252)で
必須の推奨事項になり、実装としては
iOS の SFSafariViewController / ASWebAuthenticationSession
Android の Custom Tabs を使う形に定着した
AppAuth がこれをライブラリ化している)。
これらは アプリ側から中身を覗けないうえに、
システム ブラウザの Cookie を共有するため SSO も効く。

オープン・リダイレクタ

redirect_uri の登録は、Client 側にも関係があるが、
基本的には、下記「Authorization Endpoint」の
「オープン・リダイレクタ」を参照。
(フルパス要求 = 完全一致のため)

Authorization Endpoint (Authorization Server)

Authorization Server の Authorization Endpoint に対する攻撃

偽造 Authorization Server によるフィッシング

概要

単純、且つ古典的な、偽造 Authorization Server によるフィッシング。

影響

ユーザ・アカウントを含めたあらゆる情報が取得され、それが悪用される可能性がある。

攻撃

ブラウザによる、認証情報を中心にした、あらゆる情報のフィッシング

  • DNS またはアドレス解決プロトコル(ARP)のなりすまし
  • 偽造 Client のスターターで、誤った、偽造 Authorization Server に飛ぶ。
  • 偽造 Authorization Server によりユーザ・アカウントがフィッシングされる。

対策

  • SSL/TLS(サーバ証明)の利用
  • ユーザの教育(偽造 Authorization Server の識別)

補足(教育に頼らない対策が出てきた): 「ユーザの教育」は
実効性が低いことが知られており、現在は
フィッシング耐性のある認証方式で技術的に解決する方向にある。
FIDO / WebAuthn
オリジンを鍵に紐付けるため、偽サイトでは認証情報がそもそも使えない
Passwordless の UXを参照)。

悪意のある Client に大きなアクセス権を与えてしまう

概要

認可画面の意味を理解していない場合に発生し得る。

影響

悪意のある Client が、不要に大きな scope を持ったトークンを取得できる。

攻撃

悪意のある Client が、

  • 動的に登録される。
  • 不用意に大きな scope の設定でスターターを起動。

対策

  • Resource Owner 側の要件
    Resource Owner は、認可画面を理解する。

  • Resource Server 側の要件

    • scope が広くても、Resource Server が aud をチェックしていれば影響は絞られる。
    • Resource Server が Client に限定されない共用のリソースを開示するケースは問題。
  • AuthZ 側の要件

    • client_id に対して

      • 認可画面を表示する(prompt パラメタによらず)。
      • 許可する scope をチェックする。
    • Client の Type によって許可する scope をチェックする。

      • code : 認可画面を表示。
      • token : (通常、)認可画面を表示しない。

移行メモ(助詞): 元ページの「token : (通常、)認可画面が表示しない。」は
「認可画面表示しない」の誤りと解して修正した。

悪意のある Client に既存ログイン・セッションで権限を与えてしまう

概要

既存ログイン・セッション+認可画面=非表示の場合の問題。

影響

  • ログイン・セッションが生きている場合、ログイン画面が表示されない。
  • また、認可画面が非表示の場合、なにも表示されずに権限を与えてしまう。

攻撃

悪意のある Client が、

  • 動的に登録される。
  • Client が認可画面=非表示の設定でスターターを起動。

対策

  • Resource Server 側の要件

    • 漏れても、Resource Server が aud をチェックしていれば影響は絞られる。
    • Resource Server が Client に限定されない共用のリソースを開示するケースは問題。
  • AuthZ 側の要件

    • 自動再認証の抑止
    • 認可画面=非表示の抑止
    • 上記の場合の scope を制限する。

オープン・リダイレクタ

概要

client_id さえ知っていれば、code や access_token を盗める。

影響

code や access_token が漏洩する。

  • code : Authorization Code グラント種別

    • code から access_token に変換するには、
      上記「client_secret の入手」の client_secret も必要になる。
    • code 漏洩の状態は、上記「refresh_token の入手」の状態に近い。
  • access_token : Implicit グラント種別
    access_token は、そのまま利用可能なので影響度が大きい
    (上記「access_token の入手」を参照)。

攻撃

client_id さえ知っていれば、redirect_uri のインジェクションで、
攻撃者のサイトに code や、access_token を返却させることが出来る。

対策

  • AuthZ 側の要件
    • redirect_uri のフルパス登録
    • redirect_uri のフルパス検証

補足(完全一致が標準要件になった): 「フルパス登録・検証」は
Security BCP(RFC 9700)/ OAuth 2.1
**文字列としての完全一致(exact string matching)**が
必須要件として明文化された
(ワイルドカードや前方一致は不可。ネイティブ アプリの
http://127.0.0.1:{任意ポート} のみ例外)。

Token Endpoint (Authorization Server)

Authorization Server の Token Endpoint に対する攻撃

access_token の盗聴

影響

影響は、上記「access_token の入手」と同じ。

攻撃

盗聴

対策

  • SSL/TLS の利用

  • SSL/TLS の利用できない場合。

    • access_token の scope 制限
    • access_token の有効期間を短くする。

client_secret のオンライン推測

影響

影響は、上記「client_secret の入手」と同じ。

攻撃

有効な client_id / client_secret のオンライン推測

対策

client_id, client_secret の盗聴

影響

影響は、上記「client_secret の入手」と同じ。

攻撃

盗聴

対策

  • SSL/TLS を利用する。
  • 平文認証を使用しない代替認証を使用する。

DB から access_token を盗難

影響

すべての access_token が開示される(上記「access_token の入手」)。
(1 人の Resource Owner の access_token 漏洩より影響が大きい)

攻撃

  • データベースへのアクセス権を取得
  • SQL インジェクション攻撃

対策

  • システムのセキュリティ対策を実施

  • 標準の SQL インジェクション対策を実施

  • access_token ハッシュのみを格納
    JWTの場合、DB に保存しないので対策になる)

補足(JWT なら安全、とは限らない): 「JWT なら DB に保存しないので
対策になる」は正しいが、代わりに
サーバ側で個々のトークンを失効させられないという別の問題が生じる
(有効期限が切れるまで使えてしまう)。
このため実務では、
アクセストークンは JWT で短命(数分〜1 時間)、
refresh_token は不透明トークンで DB 管理
という組み合わせが多い。
即時失効が要るなら
Token Introspection
Token Revocationを併用する。

DB から client_secret を盗難

影響

すべての client_id / client_secret が開示される(上記「client_secret の入手」)。
(1 つの Client の client_id / client_secret 漏洩より影響が大きい)

攻撃

  • データベースへのアクセス権を取得
  • SQL インジェクション攻撃

対策

  • システムのセキュリティ対策を実施
  • 標準の SQL インジェクション対策を実施

移行メモ(括弧の対応): 元ページの
「(1 つの Client の 〜 漏洩より影響が大きい)」は
開き括弧が欠けていたため補った。

補足(client_secret もハッシュで保存する): 元ページは
access_token については「ハッシュのみを格納」を挙げているが、
client_secret にも同じことが言える。
現在の実装では client_secret はハッシュ化して保存し、
発行時にしか平文を見せないのが一般的である
(GitHub などの API トークン発行画面と同じ考え方)。

参考


Tags: IT国際標準, 認証基盤, クレームベース認証, OAuth

⚠️ **GitHub.com Fallback** ⚠️