idnits 2.17.1 draft-fett-oauth-dpop-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (April 2, 2019) is 1844 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 554 -- Looks like a reference, but probably isn't: '2' on line 556 -- Looks like a reference, but probably isn't: '3' on line 558 ** Obsolete normative reference: RFC 7231 (Obsoleted by RFC 9110) ** Downref: Normative reference to an Informational RFC: RFC 7253 == Outdated reference: A later version (-17) exists of draft-ietf-oauth-mtls-13 == Outdated reference: A later version (-25) exists of draft-ietf-oauth-security-topics-12 Summary: 2 errors (**), 0 flaws (~~), 3 warnings (==), 4 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Web Authorization Protocol D. Fett 3 Internet-Draft yes.com 4 Intended status: Standards Track J. Bradley 5 Expires: October 4, 2019 Yubico 6 B. Campbell 7 Ping Identity 8 T. Lodderstedt 9 yes.com 10 M. Jones 11 Microsoft 12 April 2, 2019 14 OAuth 2.0 Demonstration of Proof-of-Possession at the Application Layer 15 draft-fett-oauth-dpop-01 17 Abstract 19 This document describes a mechanism for sender-constraining OAuth 2.0 20 tokens via a proof-of-possession mechanism on the application level. 21 This mechanism allows to detect replay attacks with access and 22 refresh tokens. 24 Status of This Memo 26 This Internet-Draft is submitted in full conformance with the 27 provisions of BCP 78 and BCP 79. 29 Internet-Drafts are working documents of the Internet Engineering 30 Task Force (IETF). Note that other groups may also distribute 31 working documents as Internet-Drafts. The list of current Internet- 32 Drafts is at https://datatracker.ietf.org/drafts/current/. 34 Internet-Drafts are draft documents valid for a maximum of six months 35 and may be updated, replaced, or obsoleted by other documents at any 36 time. It is inappropriate to use Internet-Drafts as reference 37 material or to cite them other than as "work in progress." 39 This Internet-Draft will expire on October 4, 2019. 41 Copyright Notice 43 Copyright (c) 2019 IETF Trust and the persons identified as the 44 document authors. All rights reserved. 46 This document is subject to BCP 78 and the IETF Trust's Legal 47 Provisions Relating to IETF Documents 48 (https://trustee.ietf.org/license-info) in effect on the date of 49 publication of this document. Please review these documents 50 carefully, as they describe your rights and restrictions with respect 51 to this document. Code Components extracted from this document must 52 include Simplified BSD License text as described in Section 4.e of 53 the Trust Legal Provisions and are provided without warranty as 54 described in the Simplified BSD License. 56 Table of Contents 58 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 59 1.1. Conventions and Terminology . . . . . . . . . . . . . . . 3 60 2. Main Objective . . . . . . . . . . . . . . . . . . . . . . . 3 61 3. Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 62 4. DPoP JWT Syntax . . . . . . . . . . . . . . . . . . . . . . . 5 63 5. Token Request (Binding Tokens to a Public Key) . . . . . . . 6 64 6. Resource Access (Proof of Possession for Access Tokens) . . . 8 65 7. Refresh Token Usage (Proof of Possession for Refresh Tokens) 8 66 8. Public Key Confirmation . . . . . . . . . . . . . . . . . . . 8 67 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 9 68 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 69 10.1. OAuth Access Token Type Registration . . . . . . . . . . 9 70 10.2. JWT Confirmation Methods Registration . . . . . . . . . 10 71 10.3. JSON Web Signature and Encryption Type Values 72 Registration . . . . . . . . . . . . . . . . . . . . . . 10 73 11. Security Considerations . . . . . . . . . . . . . . . . . . . 10 74 11.1. Token Replay at the Same Authorization Server . . . . . 10 75 11.2. Token Replay at the Same Resource Server Endpoint . . . 11 76 11.3. Signed JWT Swapping . . . . . . . . . . . . . . . . . . 11 77 11.4. Comparison to mTLS and OAuth Token Binding . . . . . . . 11 78 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 11 79 12.1. Normative References . . . . . . . . . . . . . . . . . . 11 80 12.2. Informative References . . . . . . . . . . . . . . . . . 12 81 12.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 12 82 Appendix A. Document History . . . . . . . . . . . . . . . . . . 13 83 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 13 85 1. Introduction 87 [I-D.ietf-oauth-mtls] describes methods to bind (sender-constrain) 88 access tokens using mutual Transport Layer Security (TLS) 89 authentication with X.509 certificates. 91 [I-D.ietf-oauth-token-binding] provides mechanisms to sender- 92 constrain access tokens using HTTP token binding. 94 Due to a sub-par user experience of TLS client authentication in user 95 agents and a lack of support for HTTP token binding, neither 96 mechanism can be used if an OAuth client is a Single Page Application 97 (SPA) running in a web browser. 99 This document outlines an application-level sender-constraining for 100 access tokens and refresh tokens that can be used if neither mTLS nor 101 OAuth Token Binding are available. It uses proof-of-possession based 102 on a public/private key pair and application-level signing. 104 DPoP can be used with public clients and, in case of confidential 105 clients, can be combined with any client authentication method. 107 1.1. Conventions and Terminology 109 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 110 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 111 "OPTIONAL" in this document are to be interpreted as described in BCP 112 14 [RFC2119] [RFC8174] when, and only when, they appear in all 113 capitals, as shown here. 115 This specification uses the terms "access token", "refresh token", 116 "authorization server", "resource server", "authorization endpoint", 117 "authorization request", "authorization response", "token endpoint", 118 "grant type", "access token request", "access token response", and 119 "client" defined by The OAuth 2.0 Authorization Framework [RFC6749]. 121 2. Main Objective 123 Under the attacker model defined in [I-D.ietf-oauth-security-topics], 124 the mechanism defined by this specification tries to ensure that 125 token replay at a different endpoint is prevented. 127 More precisely, if an adversary is able to get hold of an access 128 token because it set up a counterfeit authorization server or 129 resource server, the adversary is not able to replay the respective 130 access token at another authorization or resource server. 132 Secondary objectives are discussed in Section 11. 134 3. Concept 135 +--------+ +---------------+ 136 | |--(A)-- Token Request ------------------->| | 137 | Client | (DPop-Binding/Proof) | Authorization | 138 | | | Server | 139 | |<-(B)-- PoP Access Token -----------------| | 140 | | (token_type=Bearer+DPoP) +---------------+ 141 | | PoP Refresh Token for public clients 142 | | 143 | | +---------------+ 144 | |--(C)-- PoP Access Token ---------------->| | 145 | | (DPoP-Proof) | Resource | 146 | | | Server | 147 | |<-(D)-- Protected Resource ---------------| | 148 | | +---------------+ 149 +--------+ 151 Figure 1: Basic DPoP Flow 153 The new elements introduced by this specification are shown in 154 Figure 1: 156 o (A) In the Token Request, the client sends an authorization grant, 157 e.g., an authorization code or a refresh token, to the 158 authorization server in order to obtain an access token (and 159 potentially a refresh token). The client proves the possession of 160 a private key belonging to some public key by sending a request 161 header containing a JWT that was signed using this private key. 162 The corresponding public key is contained in the same request. 164 o (B) The AS binds (sender-constrains) the access token to the 165 public key claimed by the client; that is, the access token cannot 166 be used without proving possession of the respective private key. 167 This is signaled to the client by using the "token_type" value 168 "Bearer+DPoP". If a refresh token is issued to the client, it is 169 sender-constrained in the same way if the client is a public 170 client. Note: refresh tokens are automatically bound to the 171 "client_id" of a confidential client, which is more flexible than 172 binding it to a particular public key. 174 o (C) If the client wants to use the access token, it has to prove 175 possession of the private key by adding a header to the request 176 that, again, contains a JWT signed with this private key. The JWT 177 contains the endpoint URL and the request method. The resource 178 server needs to receive information about which public key to 179 check against. This information is either encoded directly into 180 the access token, for JWT structured access tokens, or provided at 181 the token introspection endpoint of the authorization server 182 (request not shown). 184 o (D) The resource server refuses to serve the request if the 185 signature check fails or the data in the JWT do not match, e.g., 186 the request URI does not match the URI claim in the JWT. 188 o Steps (A) and (B) can be repeated using a refresh token to obtain 189 fresh access tokens. In this case, the client sends a DPoP proof 190 JWT as in step (C) above. The client can optionally proof the 191 possession of a new private/public key pair to which the new 192 tokens are then bound by the authorization server. Otherwise, the 193 authorization server binds the new tokens to the previously used 194 public key. 196 The mechanism presented herein is not a client authentication method. 197 In fact, a primary use case are public clients (single page 198 applications) that do not use client authentication. Nonetheless, 199 DPoP is designed such that it is compatible with "private_key_jwt" 200 and all other client authentication methods. 202 Note: DPoP does not directly ensure message integrity but relies on 203 the TLS layer for that purpose. 205 4. DPoP JWT Syntax 207 DPoP uses so-called DPoP JWTs for binding public keys (DPoP Binding 208 JWT) and proving knowledge about private keys (DPoP Proof JWT). 210 A DPoP JWT is a JWT ([RFC7519]) that is signed (using JWS, [RFC7515]) 211 using a private key chosen by the client (see below). The header of 212 a DPoP JWT contains the following fields: 214 o "typ": type header, value "dpop_binding+jwt" for a DPoP Binding 215 JWT or "dpop_proof+jwt" for a DPoP Proof JWT (REQUIRED). 217 o "alg": a digital signature algorithm identifier as per [RFC7518] 218 (REQUIRED). MUST NOT be "none" or an identifier for a symmetric 219 algorithm (MAC). 221 The body of a DPoP JWT contains the following fields: 223 o "jti": Unique identifier for this JWT chosen freshly when creating 224 the JWT (REQUIRED). SHOULD be used by the AS for replay detection 225 and prevention. See Security Considerations [1]. 227 o "http_method": The HTTP method for the request to which the JWT is 228 attached, in upper case ASCII characters, as defined in [RFC7231] 229 (REQUIRED). 231 o "http_uri": The HTTP URI used for the request, without query and 232 fragment parts (REQUIRED). 234 o "exp": Expiration time of the JWT (REQUIRED). See Security 235 Considerations [2]. 237 o "cnf": Confirmation claim as per [RFC7800] containing a member 238 "dpop+jwk", representing the public key chosen by the client in 239 JWK format (REQUIRED for DPoP Binding JWTs, OPTIONAL for DPoP 240 Proof JWTs). 242 An example DPoP JWT is shown in Figure 2. 244 { 245 "typ": "dpop_binding+jwt", 246 "alg": "ES512", 247 }.{ 248 "jti": "HK2PmfnHKwXP", 249 "http_method": "POST", 250 "http_uri": "https://server.example.com/token", 251 "exp": "..." 252 "cnf":{ 253 "dpop+jwk": { 254 "kty" : "EC", 255 "kid" : "11", 256 "crv" : "P-256", 257 "x" : "usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8", 258 "y" : "3BttVivg+lSreASjpkttcsz+1rb7btKLv8EX4" 259 } 260 } 261 } 263 Figure 2: Example JWT contents for "DPoP-Binding" header. 265 5. Token Request (Binding Tokens to a Public Key) 267 To bind a token to a public key in the token request, the client MUST 268 provide a public key and prove the possession of the corresponding 269 private key. The HTTPS request shown in Figure 3 illustrates the 270 protocol for this (with extra line breaks for display purposes only). 272 POST /token HTTP/1.1 273 Host: server.example.com 274 Content-Type: application/x-www-form-urlencoded;charset=UTF-8 275 DPoP-Binding: eyJhbGciOiJSU0ExXzUi ... 277 grant_type=authorization_code 278 &code=SplxlOBeZQQYbYS6WxSbIA 279 &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb 280 (remainder of JWK omitted for brevity) 282 Figure 3: Token Request for a DPoP bound token. 284 The HTTP header "DPoP-Binding" MUST contain a DPoP Binding JWT signed 285 using the private key chosen by the client. 287 It is RECOMMENDED that clients reuse the same JWT if possible to 288 improve the performance of the client, the data transfer (caching), 289 and the authorization server. 291 If the authorization server receives a "DPoP-Binding" header in a 292 token request, the authorization server MUST check that: 294 1. the header value is a well-formed JWT, 296 2. all required claims are contained in the JWT, 298 3. the "typ" field in the header has the correct value, 300 4. the algorithm in the header of the JWT designates a digital 301 signature algorithm, is not "none", is supported by the 302 application, and is deemed secure, 304 5. the JWT is signed using the public key contained in the "cnf" 305 claim of the JWT, 307 6. the "http_method" and "http_uri" claims match the respective 308 values for the HTTP request in which the header was received, 310 7. the token has not expired, and 312 8. if replay protection is desired, that a JWT with the same "jti" 313 value has not been received previously. 315 If these checks are successful, the authorization server MUST 316 associate the access token with the public key. It then sets 317 "token_type" to "Bearer+DPoP" in the token response. The client MAY 318 use the value of the "token_type" parameter to determine whether the 319 server supports the mechanisms specified in this document. 321 6. Resource Access (Proof of Possession for Access Tokens) 323 To make use of an access token that is token-bound to a public key 324 using DPoP, a client MUST prove the possession of the corresponding 325 private key. More precisely, the client MUST create a DPoP Proof JWT 326 and sign it using the previously chosen private key. The signed JWT 327 MUST then be sent in the "DPoP-Proof" request header. 329 If a resource server detects that an access token that is to be used 330 for resource access is bound to a public key using DPoP (via the 331 methods described in Section 8) it MUST check that: 333 1. a header "DPoP-Proof" was received in the HTTP request, 335 2. the header's value is a well-formed DPoP Proof JWT, 337 3. all required claims are contained in the JWT, 339 4. the algorithm in the header of the JWT designates a digital 340 signature algorithm, is not "none", is supported by the 341 application, and is deemed secure, 343 5. the JWT is signed using the public key to which the access token 344 was bound, 346 6. the "typ" field in the header has the correct value, 348 7. the "http_method" and "http_uri" claims match the respective 349 values for the HTTP request in which the header was received, 351 8. the token has not expired, and 353 9. if replay protection is desired, that a JWT with the same "jti" 354 value has not been received previously. 356 If any of these checks fails, the resource server MUST NOT grant 357 access to the resource. 359 7. Refresh Token Usage (Proof of Possession for Refresh Tokens) 361 At the token endpoint, public clients using a refresh token MUST 362 provide a proof of possession in the same way as for access tokens. 364 8. Public Key Confirmation 366 It MUST be ensured that resource servers can reliably identify 367 whether a token is bound using DPoP and learn the public key to which 368 the token is bound. 370 Access tokens that are represented as JSON Web Tokens (JWT)[RFC7519] 371 MUST contain information about the DPoP public key (in JWK format) in 372 the member "dpop+jwk" of the "cnf" claim, as shown in Figure 4. 374 { 375 "iss": "https://server.example.com", 376 "sub": "something@example.com", 377 "exp": 1493726400, 378 "nbf": 1493722800, 379 "cnf":{ 380 "dpop+jwk": { 381 "kty" : "EC", 382 "kid" : "11", 383 "crv" : "P-256", 384 "x" : "usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8", 385 "y" : "3BttVivg+lSreASjpkttcsz+1rb7btKLv8EX4" 386 } 387 } 388 } 390 Figure 4: Example access token body with "cnf" claim. 392 When access token introspection is used, the same "cnf" claim as 393 above MUST be contained in the introspection response. 395 9. Acknowledgements 397 This document resulted from discussions at the 4th OAuth Security 398 Workshop in Stuttgart, Germany. We thank the organizers of this 399 workshop (Ralf Kuesters, Guido Schmitz). 401 10. IANA Considerations 403 10.1. OAuth Access Token Type Registration 405 This specification registers the following access token type in the 406 OAuth Access Token Types registry defined in [RFC6749]. 408 o Type name: "Bearer+DPoP" 410 o Additional Token Endpoint Response Parameters: (none) 412 o HTTP Authentication Scheme(s): Bearer 414 o Change controller: IETF 416 o Specification document(s): [[ this specification ]] 418 10.2. JWT Confirmation Methods Registration 420 This specification requests registration of the following value in 421 the IANA "JWT Confirmation Methods" registry [IANA.JWT.Claims] for 422 JWT "cnf" member values established by [RFC7800]. 424 o Confirmation Method Value: "dpop+jwk" 426 o Confirmation Method Description: JWK encoded public key for dpop 427 proof token 429 o Change Controller: IESG 431 o Specification Document(s): [[ this specification ]] 433 10.3. JSON Web Signature and Encryption Type Values Registration 435 This specification registers the "dpop_proof+jwt" and 436 "dpop_binding+jwt" type values in the IANA JSON Web Signature and 437 Encryption Type Values registry [RFC7515]: 439 o "typ" Header Parameter Value: "dpop_proof+jwt" 441 o Abbreviation for MIME Type: None 443 o Change Controller: IETF 445 o Specification Document(s): [[ this specification ]] 447 o "typ" Header Parameter Value: "dpop_binding+jwt" 449 o Abbreviation for MIME Type: None 451 o Change Controller: IETF 453 o Specification Document(s): [[ this specification ]] 455 11. Security Considerations 457 The Prevention of Token Replay at a Different Endpoint [3] is 458 achieved through the binding of the DPoP JWT to a certain URI and 459 HTTP method. 461 11.1. Token Replay at the Same Authorization Server 463 If an adversary is able to get hold of an DPoP-Binding JWT, it might 464 replay it at the authorization server's token endpoint with the same 465 or different payload. The issued access token is useless as long as 466 the adversary does not get hold of a valid DPoP-Binding JWT for the 467 corresponding resource server. 469 11.2. Token Replay at the Same Resource Server Endpoint 471 If an adversary is able to get hold of a DPoP-Proof JWT, the 472 adversary could replay that token later at the same endpoint (the 473 HTTP endpoint and method are enforced via the respective claims in 474 the JWTs). To prevent this, clients MUST limit the lifetime of the 475 JWTs, preferably to a brief period. Furthermore, the "jti" claim in 476 each JWT MUST contain a unique (incrementing or randomly chosen) 477 value, as proposed in [RFC7253]. Resource servers SHOULD store 478 values at least for the lifetime of the respective JWT and decline 479 HTTP requests by clients if a "jti" value has been seen before. 481 11.3. Signed JWT Swapping 483 Servers accepting signed DPoP JWTs MUST check the "typ" field in the 484 headers of the JWTs to ensure that adversaries cannot use JWTs 485 created for other purposes in the DPoP headers. 487 11.4. Comparison to mTLS and OAuth Token Binding 489 o mTLS stronger against intercepted connections 491 12. References 493 12.1. Normative References 495 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 496 RFC 6749, DOI 10.17487/RFC6749, October 2012, 497 . 499 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 500 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 501 DOI 10.17487/RFC7231, June 2014, 502 . 504 [RFC7253] Krovetz, T. and P. Rogaway, "The OCB Authenticated- 505 Encryption Algorithm", RFC 7253, DOI 10.17487/RFC7253, May 506 2014, . 508 [RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, 509 DOI 10.17487/RFC7518, May 2015, 510 . 512 [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token 513 (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, 514 . 516 12.2. Informative References 518 [I-D.ietf-oauth-mtls] 519 Campbell, B., Bradley, J., Sakimura, N., and T. 520 Lodderstedt, "OAuth 2.0 Mutual TLS Client Authentication 521 and Certificate-Bound Access Tokens", draft-ietf-oauth- 522 mtls-13 (work in progress), February 2019. 524 [I-D.ietf-oauth-security-topics] 525 Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, 526 "OAuth 2.0 Security Best Current Practice", draft-ietf- 527 oauth-security-topics-12 (work in progress), March 2019. 529 [I-D.ietf-oauth-token-binding] 530 Jones, M., Campbell, B., Bradley, J., and W. Denniss, 531 "OAuth 2.0 Token Binding", draft-ietf-oauth-token- 532 binding-08 (work in progress), October 2018. 534 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 535 Requirement Levels", BCP 14, RFC 2119, 536 DOI 10.17487/RFC2119, March 1997, 537 . 539 [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web 540 Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 541 2015, . 543 [RFC7800] Jones, M., Bradley, J., and H. Tschofenig, "Proof-of- 544 Possession Key Semantics for JSON Web Tokens (JWTs)", 545 RFC 7800, DOI 10.17487/RFC7800, April 2016, 546 . 548 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 549 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 550 May 2017, . 552 12.3. URIs 554 [1] #Security 556 [2] #Security 558 [3] #Objective_Replay_Different_Endpoint 560 Appendix A. Document History 562 [[ To be removed from the final specification ]] 564 -00 566 o first draft 568 -01 570 o fixed inconsistencies 572 o moved binding and proof messages to headers instead of parameters 574 o extracted and unified definition of DPoP JWTs 576 o improved description 578 Authors' Addresses 580 Daniel Fett 581 yes.com 583 Email: mail@danielfett.de 585 John Bradley 586 Yubico 588 Email: ve7jtb@ve7jtb.com 590 Brian Campbell 591 Ping Identity 593 Email: bcampbell@pingidentity.com 595 Torsten Lodderstedt 596 yes.com 598 Email: torsten@lodderstedt.net 600 Michael Jones 601 Microsoft 603 Email: mbj@microsoft.com