OAuth Symmetric Proof of Posession for Code
Extension
Nomura Research Institute
sakimura@gmail.com
http://nat.sakimura.org/
Ping Identity
jbradley@pingidentity.com
Google
naa@google.com
Security
OAuth Working Group
The OAuth 2.0 public client utilizing authorization code grant is
susceptible to the code interception attack. This specification describe
a mechanism that acts as a control against this threat.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119.
Public clients in OAuth 2.0 is
suseptible to the code interception attack.
The code interception attack is an attack
that a malicious client intercepts the code
returned from the authorization endpoint and uses it to obtain the
access token. This is possible on a public client as there is no client
secret associated for it to be sent to the token endpoint. This is
especially true on some smartphone platform in which the code is returned to a redirect URI with a custom
scheme as there can be multiple apps that can register the same
scheme.Under this scenario, the mitigation strategy stated in section
4.4.1 of does not work as they rely on
per-client instance secret or per client instance redirect uri.
To mitigate this attack, this extension utilizes dynamically created
cryptographically random key called 'code verifier'. The code verifier
is created for every authorization request and its transformed value
called code challenge is sent to the authorization server to obtain the
authorization code. The code obtained is
then sent to the token endpoint with the code verifier and the server
compairs it with the previously received reqeust code so that it can
perfom the proof of posession of the code verifier by the client. This
works as the mitigation since the attacker would not know the one-time
key.
In addition to the terms defined in OAuth
2.0, this specification defines the following terms.
a cryptographically random string with big enough entropy that is
used to correlate the authorization request to the token request
either the code verifier itself or some transformation of it that
is sent from the client to the server in the authorization request
NOTE 1: The client and the server MAY use mutually agreed
pre-negotiated algorithm such as base64url encoding of the left most
128bit of SHA256 hash.
NOTE 2: If no algorithm has been negotiated, it is treated as the
code verifier itself.
Before starting the authorization process, the client MUST make
sure that the server supports this specification. It may be obtained
out-of-band or through some other mechanisms such as the discovery
document in OpenID Connect
Discovery. The exact mechanism on how the client obtains this
information is out of scope of this specification.
The client that wishes to use this specification MUST stop
proceeding if the server does not support this extension.
In this specification, the client sends the transformation of the
code verifier to the authorization server in the front channel. The
default transformation is not doing transformation at all. If the the
server supports, the client MAY register its desired transformation
algorithm to the server. If the algorithm is registered, the server
MUST reject any request that does not conform to the algorithm.
How does this client registers the algorithm is out of scope for
this specification.
Also, this specification does not define any transformation other
than the default transformation.
The client then creates a code verifier, code_verifier,
in the following manner.
code_verifier = high entropy cryptographic random string of length
less than 128 bytes
NOTE: code verifier MUST have high enough entropy to make it
inpractical to guess the value.
Then, the client creates a code challenge, code_challenge,
by applying the pre-negotiated algorithm between the client and the
server. The default behavior is no transofrmation, i.e., code_challenge == code_verifier.
The authorization server MUST support this 'no transformation'
algorithm.
The client sends the code challenge with the following parameter
with the OAuth 2.0 Authorization
Request:
REQUIRED. code challenge.
When the server issues a code, it MUST
associate the code_challenge value with
the code so that it can be used later.
Typically, the code_challenge value is
stored in encrypted form in the code, but
it could as well be just stored in the server in association with the
code. The server MUST NOT include the code_challenge
value in the form that any entity but itself can extract it.
Upon receipt of the code, the client
sends the request to the token endpoint. In addition to the parameters
defined in OAuth 2.0, it sends the
following parameter:
REQUIRED. code verifier
Upon receipt of the request at the token endpoint, the server
verifies it by calculating the code challenge from code_verifier value and comparing it with the
previously associated code_challenge. If
they are equal, then the successful response SHOULD be returned. If
the values are not equal, an error response indicating invalid_grant as described in section 5.2 of
OAuth 2.0 SHOULD be returned.
This specification makes a registration request as follows:
This specification registers the following parameters in the IANA
OAuth Parameters registry defined in OAuth
2.0.
Parameter name: code_verifier
Parameter usage location: Access Token Request
Change controller: OpenID Foundation Artifact Binding Working
Group - openid-specs-ab@lists.openid.net
Specification document(s): this document
Related information: None
Parameter name: code_challenge
Parameter usage location: Authorization Request
Change controller: OpenID Foundation Artifact Binding Working
Group - openid-specs-ab@lists.openid.net
Specification document(s): this document
Related information: None
The security model relies on the fact that the code verifier is not
learned or guessed by the attacker. It is vitally important to adhear to
this principle. As such, the code verifier has to be created in such a
manner that it is cryptographically random and has high entropy that it
is not practical for the attacker to guess, and if it is to be returned
inside code, it has to be encrypted in such
a manner that only the server can decrypt and extract it.
If the no transformation algorithm, which is the default algorithm,
is used, the client MUST make sure that the request channel is
adequately protected. On a platform that it is not possible, the client
and the server SHOULD utilize a transformation algorithm that makes it
reasonably hard to recalculate the code verifier from the code
challenge.
All the OAuth security analysis presented in
applies so readers SHOULD carefully follow it.
The initial draft of this specification was created by the OpenID
AB/Connect Working Group of the OpenID Foundation, by most notably of
the following people:
Naveen Agarwal, Google
Dirk Belfanz, Google
Sergey Beryozkin
John Bradley, Ping Identity
Brian Campbell, Ping Identity
Phill Hunt, Oracle
Ryo Ito, mixi
Michael B. Jones, Microsoft
Torsten Lodderstadt, Deutsche Telekom
Breno de Madeiros, Google
Prateek Mishra, Oracle
Anthony Nadalin, Microsoft
Axel Nenker, Deutsche Telekom
Nat Sakimura, Nomura Research Institute
-02
Changed title.
Changed parameter names.
Changed the default transformation algorithm and added crypto
agility.
More text in the security consideration.
Now references RFC 6819.
Recorded more contributors.
-01
Minor editorial changes.
-00
Initial version.
OpenID Connect Discovery 1.0
Nomura Research Institute,
Ltd.
Ping Identity
Microsoft
Illumila