-
Notifications
You must be signed in to change notification settings - Fork 0
MS_OAuthThreatModelRole
- 戻る(OAuth 2.0 Threat Model and Security Considerations)
- OAuth 2.0 Threat Model (Role)
- OAuth 2.0 Threat Model (Flow)
- OAuth 2.0 Threat Model (Access)
OAuth 2.0 Threat Model and Security Considerationsの
Role に着目した脅威モデル。
- Client
- Authorization Server
- Authorization Endpoint
- Token Endpoint
Client に対する攻撃
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 の漏洩により、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 の漏洩は、そのまま、リソースにアクセスが可能になる。
- 単一の Resource Owner への影響
- そのスコープのリソースにアクセスが可能になる。
上記「refresh_token の入手」と同じ攻撃。
-
Client 側の要件
- 一時メモリやプライベート・メモリに保持する。
- その他、上記「refresh_token の入手」と同じ対策。
-
AuthZ 側の要件
- access_token の scope 制限
- access_token の有効期間を短くする。
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 Server の Authorization Endpoint に対する攻撃
単純、且つ古典的な、偽造 Authorization Server によるフィッシング。
ユーザ・アカウントを含めたあらゆる情報が取得され、それが悪用される可能性がある。
ブラウザによる、認証情報を中心にした、あらゆる情報のフィッシング
- DNS またはアドレス解決プロトコル(ARP)のなりすまし
- 偽造 Client のスターターで、誤った、偽造 Authorization Server に飛ぶ。
- 偽造 Authorization Server によりユーザ・アカウントがフィッシングされる。
- SSL/TLS(サーバ証明)の利用
- ユーザの教育(偽造 Authorization Server の識別)
補足(教育に頼らない対策が出てきた): 「ユーザの教育」は
実効性が低いことが知られており、現在は
フィッシング耐性のある認証方式で技術的に解決する方向にある。
FIDO / WebAuthn は
オリジンを鍵に紐付けるため、偽サイトでは認証情報がそもそも使えない
(Passwordless の UXを参照)。
認可画面の意味を理解していない場合に発生し得る。
悪意のある Client が、不要に大きな scope を持ったトークンを取得できる。
悪意のある Client が、
- 動的に登録される。
- 不用意に大きな scope の設定でスターターを起動。
-
Resource Owner 側の要件
Resource Owner は、認可画面を理解する。 -
Resource Server 側の要件
- scope が広くても、Resource Server が
audをチェックしていれば影響は絞られる。 - Resource Server が Client に限定されない共用のリソースを開示するケースは問題。
- scope が広くても、Resource Server が
-
AuthZ 側の要件
-
client_idに対して- 認可画面を表示する(
promptパラメタによらず)。 - 許可する scope をチェックする。
- 認可画面を表示する(
-
Client の Type によって許可する scope をチェックする。
- code : 認可画面を表示。
- token : (通常、)認可画面を表示しない。
-
移行メモ(助詞): 元ページの「token : (通常、)認可画面が表示しない。」は
「認可画面を表示しない」の誤りと解して修正した。
既存ログイン・セッション+認可画面=非表示の場合の問題。
- ログイン・セッションが生きている場合、ログイン画面が表示されない。
- また、認可画面が非表示の場合、なにも表示されずに権限を与えてしまう。
悪意のある Client が、
- 動的に登録される。
- Client が認可画面=非表示の設定でスターターを起動。
-
Resource Server 側の要件
- 漏れても、Resource Server が
audをチェックしていれば影響は絞られる。 - Resource Server が Client に限定されない共用のリソースを開示するケースは問題。
- 漏れても、Resource Server が
-
AuthZ 側の要件
- 自動再認証の抑止
- 認可画面=非表示の抑止
- 上記の場合の scope を制限する。
client_id さえ知っていれば、code や access_token を盗める。
code や access_token が漏洩する。
-
code : Authorization Code グラント種別
- code から access_token に変換するには、
上記「client_secretの入手」のclient_secretも必要になる。 - code 漏洩の状態は、上記「refresh_token の入手」の状態に近い。
- code から access_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:{任意ポート}のみ例外)。
Authorization Server の Token Endpoint に対する攻撃
影響は、上記「access_token の入手」と同じ。
盗聴
-
SSL/TLS の利用
-
SSL/TLS の利用できない場合。
- access_token の scope 制限
- access_token の有効期間を短くする。
影響は、上記「client_secret の入手」と同じ。
有効な client_id / client_secret のオンライン推測
-
client_secretに高いエントロピーを使用 - 強力なクライアント認証
- (クライアント認証の)アカウント・ロック
影響は、上記「client_secret の入手」と同じ。
盗聴
- SSL/TLS を利用する。
- 平文認証を使用しない代替認証を使用する。
すべての 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を併用する。
すべての 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 トークン発行画面と同じ考え方)。
-
RFC 6819 - OAuth 2.0 Threat Model and Security Considerations
https://tools.ietf.org/html/rfc6819 -
本 Wiki 内
Tags: IT国際標準, 認証基盤, クレームベース認証, OAuth
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。