My guess is that for an Authorization Server that doesn't receive a
'code_challenge' and 'code_challenge_method' as part of the
authorization request, they treat the request as a non-PKCE
authorization request. Therefore when the 'code_verifier' is presented
at the /token endpoint, the AS ignores the parameter because it doesn't
consider the request to be a PKCE request. I can also see the AS
returning an error regarding an "unexpected parameter" or "invalid
request" error in this case.
I agree with your recommendation for the AS to require specific clients
to use PKCE and consider an authorization request without PKCE to be an
error.
Finally, I'm not sure a client that doesn't send the 'code_challenge'
and 'code_challenge_method' on the authorization request but does send
the 'code_verifier' on the token request should consider that the client
has implemented PKCE correctly and hence can rely on it for CSRF.
Thanks,
George
On 1/4/22 5:45 AM, Benjamin Häublein wrote:
Hello everyone,
I think RFC 7636 “Proof Key for Code Exchange by OAuth Public
Clients”, section 4.6. “Server Verifies code_verifier before Returning
the Tokens” leaves a tiny gap regarding the handling of verification
when no code challenge was present in the authorization request:
Upon receipt of the request at the token endpoint, the server
verifies it by calculating the code challenge from the received
"code_verifier" and comparing it with the previously associated
"code_challenge", after first transforming it according to the
"code_challenge_method" method specified by the client.
It is unspecified how the server should behave when “code_verifier” is
present, but “code_challenge” and “code_challenge_method” were not set
in the initial authorization request.
The following example worked for three well-known authorization
servers where the client was configured in a way that PKCE could be
used, but was not enforced:
Authorization Request:
https://XXXX/auth?client_id=YYYY&response_type=code&scope=openid+profile&redirect_uri=https://localhost
<https://XXXX/auth?client_id=YYYY&response_type=code&scope=openid+profile&redirect_uri=https://localhost>
Subsequent Token Request:
POST /token HTTP/1.1
Host: XXXX
Content-Length: 256
code=ZZZZ&grant_type=authorization_code&client_id=YYYY&redirect_uri=https%3A%2F%2Flocalhost&code_verifier=IqiCQGM06JEyW73AB3f3oblCQKHOorapyqHUcYRujuSikDJx8cvBQ0kmFmzW75uIfaSBtXQrRmwuk71WWO6ryCzahTcxBPYX
As a result, an access token was issued although the code_verifier
provided in the token request did not match the code_challenge and
code_challenge_method in the authorization request.
Many applications consider the usage of PKCE as enough protection from
Login-CSRF and do not use state or nonce (for example this blog entry
by Daniel Fett
https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/
suggests, that neither state nor nonce are necessary when PKCE is
used). However, when the authorization server is not configured to
require a specific code_challenge_method from the client and the
authorization behaves as described in the example, PKCE does not
protect from Login-CSRF.
I think the following mitigations are possible:
* Enforce usage of PKCE in the client configuration in the
Authorization Server
* Implementation of the authorization server returns an error in the
Access Token Response when code_verifier is present in the token
request, but no code_challenge and code_challenge_method is
present in the authorization request.
* Additionally, when the behavior of an AS is correct (verification
of code_verifier fails when no code_challenge was present), a
client that relies on PKCE for CSRF protection must always include
a code_verifier parameter in the token request (even if no
code_verifier is present on the client side).
Best regards,
Benjamin Häublein
Senior Consultant
cirosec GmbH
Ferdinand-Braun-Strasse 4
74074 Heilbronn
Germany
Phone: +49 (7131) 59455-74
Fax: +49 (7131) 59455-99
Mobile: +49 (151) 122414-74
www.cirosec.de
HRB Stuttgart 107883
CEO Stefan Strobel, CFO Peter Lips
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth