「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>UserAgentでOAuth2のTokenを取得するベスト・プラクティス]]

* 目次 [#p291d1f4]
#contents

*概要 [#jb3d7ad1]
-認可コード横取り攻撃 (authorization code interception attack) への対策

-(Authorization Codeグラント種別により発行された)~
認可コードをクライアントアプリケーションが受け取る際、~
悪意のあるアプリケーションがその認可コードを横取りする攻撃に対抗する仕様。

**課題 [#d588d1d4]
ネイティブアプリが、外部ブラウザを使用してOAuth 2.0認証要求を発行する場合、

>「[[Implicit Flow>OAuth#m5c2d510]]ではなく、[[Authorization Code Flow>OAuth#yfeb403d]]を使用し、~
redirect_uriにカスタムURIスキームを使用してcodeを取得する。」~
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 |          |
    | +----------------------------+ |                   +----------+
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+

-カスタムURIスキームの上書き攻撃によって、このcodeが傍受されることがある。
-Private-Use URI Schemeの上書き攻撃によって、このcodeが傍受されることがある。
-また、client_idや、client_secretも漏洩してしまう可能性がある。

**対策 [#j94e6ae3]
-コード交換のための証明鍵(PKCE、 "pixy"と発音)を使用して脅威を軽減する。
-プロビジョニングされたアプリケーションのバイナリ・ファイル中のclient_secretについては、~
機密性が考慮されていないため、client_secretを必要としない方式になっている。

*仕様 [#gb8fc333]
**仕様の概要 [#obb75901]
このフローは、

-Client ≒ デバイス(UserAgent)になる。

-redirect_uriにカスタムURIスキームが使用される点を除いて、~
-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]
*補足 [#odafd559]
OAuth PKCE、client_secretは不要と言うが、

-client_secret使わないで、アクセストークン・リクエストができたら安全ではない。

-理由は、悪意の有るクライアントがclient_idダケ盗んで~
Custom URL Scheme 上書き攻撃で正規のOAuth PKCEフロー実行できるため。
Private-Use URL Scheme 上書き攻撃で正規のOAuth PKCEフロー実行できるため。

-なので、重要なResourceならば、
-なので、

--Hybrid flow的に、codeとcode_verifierを、Client(フロントエンド)から~
Client(バックエンド)に渡してからアクセストークン・リクエストする必要がある。

--なお、[[Financial API (FAPI)]]の[[Read Only API Security Profile>Financial API (FAPI)#jcbf3a32]]では、~
追加のクライアント認証の実装(JWT Client Assertion、Mutual TLS)と組合せている。
追加のクライアント認証の実装([[JWT Client Assertion>JWT bearer token authorizationグラント種別]], [[Mutual TLS]])と組合せている。

*参考 [#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 2.0 for Native Apps]] [#fd72f8ea]

----
Tags: [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS