「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>OAuth#h47e1abd]] * 目次 [#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を取得する。」~ という方式があるが(下図を参照)、 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | 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が傍受されることがある。 -また、client_idや、client_secretも漏洩してしまう可能性がある。 **対策 [#j94e6ae3] -コード交換のための証明鍵(PKCE、 "pixy"と発音)を使用して脅威を軽減する。 -プロビジョニングされたアプリケーションのバイナリ・ファイル中のclient_secretについては、~ 機密性が考慮されていないため、client_secretを必要としない方式になっている。 *仕様 [#gb8fc333] **仕様の概要 [#obb75901] このフローは、 -Client ≒ デバイス(UserAgent)になる。 -[[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の生成にソルト(やストレッチ)は不要。 *参考 [#ca1689ad] **仕様 [#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 **その他 [#q48125ac] -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 拡張を利用する ---- Tags: [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]