- 追加された行はこの色です。
- 削除された行はこの色です。
「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。
-戻る
--[[OAuth 2.0 拡張]]
--[[UserAgentでOAuth2のTokenを取得するベスト・プラクティス]]
* 目次 [#p291d1f4]
#contents
*概要 [#jb3d7ad1]
認可コード横取り攻撃 (authorization code interception attack) への対策
-(Authorization Codeグラント種別により発行された)~
認可コードをクライアントアプリケーションが受け取る際、~
悪意のあるアプリケーションがその認可コードを横取りする攻撃に対抗する仕様。
-[[OpenID Connect]]の、[[Authorization Code Flow>OpenID Connect#mcde509a]]とも組み合わせることができる。
**課題 [#d588d1d4]
ネイティブアプリが、外部ブラウザを使用してOAuth 2.0認証要求を発行する場合、
>「[[Implicit Flow>OAuth#m5c2d510]]ではなく、[[Authorization Code Flow>OAuth#yfeb403d]]を使用し、~
redirect_uriにPrivate-Use URI Schemeを使用してcodeを取得する。」~
という方式があるが(下図を参照)、
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| End Device (e.g., Smartphone) |
| |
| +-------------+ +----------+ | (6) Access Token +----------+
| |Legitimate | | Malicious|<--------------------| |
| |OAuth 2.0 App| | App |-------------------->| |
| +-------------+ +----------+ | (5) Authorization | |
| | ^ ^ | Grant | |
| | \ | | | |
| | \ (4) | | | |
| (1) | \ Authz| | | |
| Authz| \ Code | | | Authz |
| Request| \ | | | Server |
| | \ | | | |
| | \ | | | |
| v \ | | | |
| +----------------------------+ | | |
| | | | (3) Authz Code | |
| | Operating System/ |<--------------------| |
| | Browser |-------------------->| |
| | | | (2) Authz Request | |
| +----------------------------+ | +----------+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
-Private-Use URI Schemeの上書き攻撃によって、このcodeが傍受されることがある。
-また、client_idや、client_secretも漏洩してしまう可能性がある。
**対策 [#j94e6ae3]
-コード交換のための証明鍵(PKCE、 "pixy"と発音)を使用して脅威を軽減する。
-プロビジョニングされたアプリケーションのバイナリ・ファイル中のclient_secretについては、~
機密性が考慮されていないため、client_secretを必要としない方式になっている。
*仕様 [#gb8fc333]
**仕様の概要 [#obb75901]
このフローは、
-Client ≒ デバイス(UserAgent)になる。
-redirect_uriにPrivate-Use URI Schemeが使用される点を除いて、~
[[Authorization Code Flow>OAuth#yfeb403d]]と同じだが、下記リクエストにパラメタが追加される。
--認証リクエスト
--Tokenリクエスト
+-------------------+
| Authz Server |
+--------+ | +---------------+ |
| |--(A)- Authorization Request ---->| | |
| | + t(code_verifier), t_m | | Authorization | |
| | | | Endpoint | |
| |<-(B)---- Authorization Code -----| | |
| | | +---------------+ |
| Client | | |
| | | +---------------+ |
| |--(C)-- Access Token Request ---->| | |
| | + code_verifier | | Token | |
| | | | Endpoint | |
| |<-(D)------ Access Token ---------| | |
+--------+ | +---------------+ |
+-------------------+
**仕様の詳細 [#sb35c097]
-Clientは、認可リクエストを送信する前に、
--乱数 "code_verifier" を発生させ、
--[[ハッシュ関数>#k363fd25]] "t" を用いた
--ハッシュ値 "t(code_verifier)"を計算する。
-Clientは、認可リクエストに以下のパラメタを含める。
--code_challenge_method:[[ハッシュ関数>#k363fd25]] "t"
--code_challenge:ハッシュ値 "t(code_verifier)"
-認可エンドポイントで、前述の認可リクエストを受信した際、これらを保存しておく。
-Clientは、Tokenリクエストに、先程生成した code_verifierパラメタを含める。
-Tokenエンドポイントでcode_verifierを含むTokenリクエストを受信した場合、保存されている
--code_challenge_method:[[ハッシュ関数>#k363fd25]] "t"
--code_challenge:ハッシュ値 "t(code_verifier)"
>を使用して、code_verifierの妥当性を検証する。
-なお、このフローでは、client_secretは不要とする。
***[[各エンドポイント>OAuth#h4dcb0c7]]で受け取るパラメタ [#rf81fec1]
-認可エンドポイント
|#|パラメタ|要否|説明|h
|1|code_challenge|必須|Code Verifier を元に計算された Code Challenge の値|
|2|code_challenge_method|任意|Code Challenge の計算に用いる[[ハッシュ関数>#k363fd25]]。&br;"plain"と"S256"があり、デフォルトは "plain"。|
-Tokenエンドポイント
|#|パラメタ|要否|説明|h
|1|code_verifier|必須|動的に作成された暗号的にランダムな43-128文字のbase64url文字列|
***ハッシュ関数 [#k363fd25]
-plain:
--恒等関数(引数と同じ戻り値を返すの意)
--code_verifierをそのまま使用する(ClientでS256がサポートできない場合)。
-S256:
--BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
--SHA-256 でハッシュ化した値を base64url に変換したもの。
***codeとの関連 [#qe9e38a1]
-サーバー・ステートレス~
通常、"code_challenge"および"code_challenge_method"の~
値は暗号化された形式で"code"自体に格納される。
-サーバー・ステートフル~
codeに関連付けられたAuthorization Serverに格納することもできるが、~
"code_challenge"と"code"を関連付ける方法は、仕様の対象外。
*セキュリティに関する考慮事項 [#id24a0d3]
**code_verifier [#k379ad67]
-code_verifierには充分なエントロピーが必要(256ビット以上)。
-生成には、適切なRNG(RNGCryptoServiceProviderなど)の使用が推奨される。
**盗聴者からの保護 [#r76df0b6]
-通常、"S256"を使用する。~
PKCEをサポートするサーバーは"S256"をサポートする必要がある。
--"plain"では、"code_challenge" = "code_verifier"となり盗聴が可能。
--従って、通常、"plain"ではなく、"S256"を使用する必要がある。
-"plain"を使用する場合、
>サーバー・ステートレスで"code"から"code_challenge"および"code_challenge_method"を~
取り出す場合の処理は、当該サーバだけが可能になるように実装する必要がある。
**code_challenge [#s821e3e8]
code_challengeの生成にソルト(やストレッチ)が不要な理由。
-ソルトによって、辞書空間が大幅に拡張される。
-しかし、
--code_verifierはpasswordと異なり、エントロピーが高い。
--GPUの進化によってソルトの価値が減ってきている。
このため、code_challengeの生成にソルト(やストレッチ)は不要。
*補足 [#odafd559]
**client_secret不要? [#k3b1f3c9]
%%OAuth PKCE、client_secretは不要と言うが、%%
**client_secret不要?問題 [#k3b1f3c9]
-%%client_secret使わないで、アクセストークン・リクエストができたら安全ではない。%%
***概要 [#q94b6549]
OAuth PKCEのアクセストークン・リクエストでは、client_secretは不要で、client_idのみでOK。
-なので、client_secret_basic ではなく、client_secret_post っぽくポスト送付したりする。
-Auth0では、client_secret_post でもなく、client_secret_query 的だったらしい。
-%%理由は、悪意の有るクライアントがclient_idダケ盗んで%%~
%%Private-Use URL Scheme 上書き攻撃で正規のOAuth PKCEフロー実行できるため。%%
***参考 [#s63ff1ec]
-OSSコンソーシアム
--PKCEのトークンリクエストはフロントエンドから?バックエンドから?
---①~
https://www.osscons.jp/jorfs4g6d-537
---②~
https://www.osscons.jp/joxql6yjz-537
-%%なので、%%
--%%Hybrid flow的に、codeとcode_verifierを、Client(フロントエンド)から%%~
%%Client(バックエンド)に渡してからアクセストークン・リクエストする必要がある。%%
--%%なお、[[Financial API (FAPI)]]では、[[追加のクライアント認証>JWTとOAuth2.0#pebd83d3]]と組合せている。%%
OAuth PKCEでは、client_secretは不要で、client_idのみ、~
client_secret_basic ではなく、client_secret_post っぽくポスト送付する模様。
-PKCEのトークンリクエストはフロントエンドから?バックエンドから? - OSSコンソーシアム~
https://www.osscons.jp/jorfs4g6d-537/#_537
**オレオレPKCE [#t885d050]
***概要 [#fdf40453]
-OAuth PKCEをサポートしていない Idp/Sts でClient側に実装を足して、~
PKCEッポくする処理シーケンス(本来は、リプレース予算の獲得するのが望ましい)。
-よりセキュアに、OAuth PKCEっぽく実装する場合、~
code_verifierをそのまま使用するのではなく、以下のcode_challengeとして送信する。~
なお、アルゴリズム(code_challenge_method)は、今の所、"plain"と"S256"のみ。
--code_challenge_method:ハッシュ関数 "t"
--code_challenge:ハッシュ値 "t(code_verifier)"
***フロー [#y5663f4b]
① Resource Owner(ユーザ)がスマホ上のClient(スマホネイティブ・アプリ)をクリックする。
② Client(スマホネイティブ・アプリ)が起動する。
③ Client(スマホネイティブ・アプリ)のログイン ボタン or リンクをクリックする。
④ 外部ブラウザが起動して、Client(バックエンドWebアプリ)へWebアクセスする。~
☆ CSRF対策、カスタムURLスキーム上書き攻撃対策として、~
Client(スマホネイティブ・アプリ)は、固定でないstateに加えcode_verifierパラメタ付加しておく。~
※ stateとcode_verifierパラメタは後で使用するので、Client(スマホネイティブ・アプリ)のローカル領域に保存しておく。
[ここからOAuth2のAuthoriaztion Codeフローでの認証]
⑤ Client(バックエンドWebアプリ)はClient(スマホネイティブ・アプリ)の要求を受けて~
Authorization Serverへリダイレクト(OAuth2のAuthoriaztion Codeを開始)する。~
☆ CSRF対策として、Client(バックエンドWebアプリ)は、~
Client(スマホネイティブ・アプリ)から渡されたstateパラメタを付加する。
⑥ Authorization Serverがログイン画面を表示する。
⑦ Resource Owner(ユーザ)がクレデンシャル(ID, PWD)を入力する。
⑧ Authorization ServerはAuthoriaztion Code(code)を発行し~
Client(バックエンドWebアプリ)のRedirectエンドポイントへリダイレクトする。
⑨ Client(バックエンドWebアプリ)は、先ず、stateパラメタを検証し、stateが問題なければ、~
Authorization ServerのTokenエンドポイントへ AccessTokenリクエスト(codeを提示)する。
⑩ Authorization ServerからClient(バックエンドWebアプリ)へAccessToken発行
⑪ Client(バックエンドWebアプリ)は、AccessTokenを使用してUserInfoエンドポイントにリクエストし、~
ユーザー情報が取得できたらユーザがログイン(認証/認可)されたこととする。
[ここまでOAuth2のAuthoriaztion Codeフローでの認証]
⑫ Client(バックエンドWebアプリ)は、Client(スマホネイティブ・アプリ)用の一時codeを生成してcode_verifierと紐つけて保持する。
⑬ 次に、カスタムURLスキームでClient(スマホネイティブ・アプリ)へリダイレクトし、これによって、一時codeとstateを渡す。
⑭ Client(スマホネイティブ・アプリ)は、一時codeとstateを受け取り、先ず、state検証する。~
stateが問題なければ、一時codeと、④で指定したcode_verifierをClient(バックエンドWebアプリ)のTokenエンドポイントへポストする。
⑮ Client(バックエンドWebアプリ)のTokenエンドポイントは、~
codeとcode_verifierを検証し、問題なければ認証tokenを発行する。
⑯ Client(スマホネイティブ・アプリ)は、認証tokenを取得する。
⑰ Client(スマホネイティブ・アプリ)は、 認証tokenを使用して~
Client(バックエンドWebアプリ)のWebAPIへアクセスし、~
正常系のリターンがあれば、ユーザがログイン(認証/認可)されたこととする。
**スマホ向けPKCE [#i133571b]
***[[Authorization Code Grant Flow with PKCE]] [#f3cfb634]
[[SPA>Single-page application]]でPKCEする場合のプロファイル。
*参考 [#ca1689ad]
-RFC7636として発行されたOAuth PKCEとは - r-weblife~
http://d.hatena.ne.jp/ritou/20151018/1445181974
-PKCE: 認可コード横取り攻撃対策のために~
OAuth サーバーとクライアントが実装すべきこと - Qiita~
https://qiita.com/TakahikoKawasaki/items/00f333c72ed96c4da659
-OAuth2.0で認可コードの漏洩を防ぐPKCE - 理系学生日記~
http://kiririmode.hatenablog.jp/entry/20170206/1486306800
--OAuth 2.0 and PKCE | Pedro Félix's shared memory~
https://blog.pedrofelix.org/2016/02/15/oauth-2-0-and-pkce/
-OAuth for Native Apps | GREE Engineers' Blog~
http://labs.gree.jp/blog/2015/12/14831/
--解決策1-2: OAuth PKCE 拡張を利用する
**仕様 [#g417e99c]
-RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients~
https://tools.ietf.org/html/rfc7636
--OAuth 2.0 Threat Model and Security Considerations~
https://www.rfc-editor.org/rfc/rfc6819.txt
--Recommendations for Secure Use of~
Transport Layer Security (TLS)~
and Datagram Transport Layer Security (DTLS)~
https://www.rfc-editor.org/rfc/rfc7525.txt
**関連 [#xe006d83]
***[[OAuth PKCE利用時の構成図>UserAgentでOAuth2のTokenを取得するベスト・プラクティス#nd4ecb50]] [#l2a04fa7]
***[[OAuth 2.0 for Native Apps]] [#fd72f8ea]
***[[OAuth 2.0 for Browser-Based Apps]] [#m5706070]
----
Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]