authentication – Is PKCE really protecting public facing clients? Can’t a rogue app steal the ClientID and Secret and make a AuthCode request of its own?

From what I have understood, for public facing clients such as JavaScript apps that run on the browser or mobile apps which have no backend there is no secure place to store client id and secret. Therefore, the client will generate a random string code a.k.a code challenge (plain).

And then:

Client sends ClientID, secret, redirect URI and code challenge --> Authorization Server 
--> Auth Server sends back Auth Code --> Client --> Sends the previously generated code challenge (string) 
--> Auth Server --> Auth Server checks if the code challenge is same as the one that was sent earlier
 when it generated that particular Auth Code. --> Auth Server Sends back Access token.

How does this secure the client application? I mean that if someone can steal the ClientID and secret then it can also generate a random string and send all three to the Authorization server to generate Auth Code and then make another request to get the access token. Eventually the token would expire and then the person could repeat the process since it has the ClientID and Secret. It is just a matter of generating that random code challenge again.

I understand that Hacker App can not use the stolen AuthCode to get Access Token because of PKCE but – why can’t Hacker app use the clientID of your app and generate a code verifier then ask Authorization Server for a Auth Code and then again for Access Code?

Is it impossible to steal ClientID?
When Authorization sever sends back the AuthCode to the client. Is that the only point which is vulnerable?

I have been through this post but I am still not clear on this.

Why does PKCE for Oauth2.0 hash the ascii bytes instead of the original bytes?

Maybe this is not a useful question, but I got a little hung up on this because it seems a little strange. In the example of the PKCE verification in RFC-7636 it details the following:

The client uses output of a suitable random number generator to
   create a 32-octet sequence.  The octets representing the value in
   this example (using JSON array notation) are:

      (116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173,
      187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83,
      132, 141, 121)

   Encoding this octet sequence as base64url provides the value of the


   The code_verifier is then hashed via the SHA256 hash function to

     (19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46,
      8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203,
      112, 249, 195)

The part that seems strange is that the bytes from the first random byte sequence are not hashed to generate the challenge, the ascii bytes of the base64url-encoded string are hashed. Is there any reason for this? Why not just hash the original bytes?

oauth – Why not use PKCE for backend apps, too?

So for SPA/frontend apps, you should be using PKCE these days for OAuth flow. But the backend apps have this additional complexity of having to have a secret key and use that key to talk to the token endpoint. Why not just use PKCE on the backend, too?

oauth – Does PKCE replace customer secrets?

This is a more direct question "yes" or "no" to the following questions

PKCE vs Client Secret

What is the OAuth2 client secret for?

Does PKCE override the state in the OAuth stream of the authorization code?

I guess the answer is "yes" based on the above so only the client_id is necessary and the generation of secret is managed by the client via its code verifiers. If that were the case, why would Google continue to use customer secrets for their OAuth 2.0 client IDs (except if they are equivalent to secret client IDs are the API keys that I have not verified as their PKCE)

oauth2 – OpenID Connect with authorization code flow and PKCE – How can we get a new access token in a SPA application?

As answered this question, single page applications should not receive a refresh token with the OIDC authorization code stream.

Can you indicate a way to get a new access token when it expires (without interrupting the SPA UX state (no redirection …)?

If using refresh tokens was the only solution, how can we minimize the risk of leakage? For example: is it safe enough to store it in the browser's session memory? Do IdPs provide some form of expiration of refresh_token, etc.

hash – Oauth2 PKCE – What is the security provided by "S256" compared to "plain"?

The Oauth PKCE protocol flow is as follows, as defined in RFC 7636:

                                             |   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 ---------|               | |
   +--------+                                | +---------------+ |

My question is: why should we use a hatch such as S256 at step (A)?

According to the RFC threat model, a malicious application can not intercept the outgoing communication in (A) or (C). So, why can not an application temporarily generate and store a random value in (A) and reuse it in (C)?

Develop: the goal of t(code_verifier) (that is to say S256(code_verifier)) is to allow the application later to prove to the server that it is indeed the application as it is code_verifier before the transformation.

However, if the application just sent code_verifier and later it sends it again, the same guarantee is obtained: the server receives a random value that uniquely identifies the application and receives it again. No other application can provide this value: as long as the connection is not intercepted (and should not be - TLS), S256 seems useless.

rest – Why does PKCE protect against "man-in-the-middle" attacks?

When trying to implement OAuth2 in a native-installed client application, we are faced with the following problem: we can not securely store the pre-shared client secret. After some research, I came across PKCE, which I had never heard of before. Exchanging the client's secret against an ephemeral nuncio seems like a reasonable idea, but I do not see how to protect ourselves from what appears to be a fairly clear "middle man" attack. My thought is:

The flow begins when Alice sends Bob a hash code challenge with an assertion of his identity (such as a session token). The challenge is hashed because one can not assume that it is secure. The server stores the hash code request but otherwise follows basic OAuth2 and returns an authorization code. All is well until now.

The next step is for Alice to send Bob the authorization code and the now unstamped challenge code, all encrypted in a POST HTTPS request. Bob can validate the code challenge by hashing the value and comparing it with the previous hash, and generating an access token for the authorization code.

I understand that the reason "this is safer" is because an interceptor ("Eve") would not have the challenge value of plain text code in the second step, and therefore, even if they heard the authorization code, they could not ask for an access token. What concerns me, however, is Eve not just able to intercept the initial application and swap the chopped code challenge against the challenge that she created herself? Then, the authorization code would be associated with this challenge and not with that of Alice!

I've gone around the question several times and I came across being happy. I understand it and I am not convinced. So it's probably a case I've thought too much about. But if anyone could explain why I'm wrong in simple English, I would appreciate it a lot 🙂

Thanks in advance!