Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In OpenID Connect with PKCE, how does the client know which code_verifier to send with which authorization code after user redirect?

I'm taking a ASP.NET security course on OpenID Connect authorization code workflow with PKCE protection against code replay attack. There is one aspect of this process that I don't understand.

The process:

  1. Relying client generates PKCE code_verifier, hash it into code_challenge, and send the user to the authorization server with the code_challenge as a query parameter.

  2. The authorization server stores the code_challenge, issues authorization code, and redirects user back to client with the authorization code.

  3. The client sends the authorization code along with the original code_verifier to exchange for tokens. The authorization server verifies that the code_verifier indeed hashes into code_challenge before issuing the token.

My question is step #3: since HTTP is stateless, how does the client know which code_verifier to send along with the authorization code? Is this code_verifier stored in a cookie on the user agent?

like image 754
thankyoussd Avatar asked Oct 23 '25 19:10

thankyoussd


1 Answers

Using a cookie to store the "code verifier" appears to violate the spirit of the OpenId specification and just appears to be a big security hole.

In brief, the spec expects you to use S256 to hash the code verifier and the code verifier to be kept secret from eavesdropping or being guessed.

PKCE RFC Section 7.1 says the "The security model relies on the fact that the code verifier is not learned or guessed by the attacker. It is vitally important to adhere 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." ... "The use of "S256" protects against disclosure of the "code_verifier" value to an attacker."

Now it does give an opening to using a cookie if you encrypt the "code verifier". Here is the what the spec says in Section 7.2: "If the code challenge method is "plain" and the code challenge is to be returned inside authorization "code" to achieve a stateless server, it MUST be encrypted in such a manner that only the server can decrypt and extract it."

Well, OpenId specification has a solution and Microsoft has provided an implementation to follow. Refer to the "state" parameter in the OpenId specification when calling the "authorization" endpoint. The Identity Providers will return the value back to the caller.

The way it is done in .NET Core is using the "state" query string parameter whereby the value is a dictionary but protected (encrypted). For help look through the .NET core code and look at the method "BuildChallengeUrl" in "Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler"

Also, this Site has a great idea that works. It's a valid option.

like image 139
Blake Avatar answered Oct 27 '25 01:10

Blake



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!