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?


(This is a best guess as I am not a OAuth expert nor user).

RFC7636 created PKCE to incapacitate attackers with access to both client source code and relevant client communications. This is for example the case of some mobile applications which cannot ship secrets directly to the client device and cannot prevent other applications on the same device from sniffing the OAuth callback.

On most servers there isn't this kind of risk, as one can directly deploy secrets in a secure manner. On those servers PKCE would create unnecessary complexity. Complexity would both create new security risks and would divert resources which would be better spent mitigating more applicable security risks.

See also this YouTube video explaining the difference between confidential and public clients.

  • I understand the history, but I do not see what is the complexity on the server side you are talking about. I mean, having the same code/logic on frontend and backend is better, makes overall complexity smaller, and also you do not have to worry about secrets management. – Mitar Feb 23 at 5:07
  • @Mitar you'd still worry about server secrets management, as your server would have to authenticate to the OAuth authentication server before he can use PKCE. Moreover if the OAuth Resource Owner can access other resources, a compromised server would have greater impact. – Enos D'Andrea Feb 23 at 6:06
  • Why would the server have to authenticate? It would do exactly the same flow as the frontend does, so no secrets? It would just temporary have to store the PKCE state. So if I register a public client with the OAuth authentication server, but do the flow from the backend side. The server would not know that. – Mitar Feb 23 at 6:33
  • @Mitar I suggest to describe your use case in detail within the initial question. – Enos D'Andrea Feb 23 at 8:15

Having PKCE for confidential clients is a good idea. The draft for OAuth 2.1 requires PKCE for all clients.
In the summary the first bullet point reads:

PKCE is required for all OAuth clients using the authorization code flow

Having a confidential client is still relevant, as you can make sure, that only authenticated clients can get access tokens.
If you have a public client with PKCE an attacker can get access tokens from the Authorization server by impersonating a client. (In that case the attacker just needs to randomly create a code verifier and the corresponding challenge, then create an authorization request and handle the response and token request himself).

  • Interesting. I didn't know about OAuth 2.1 and PKCE in there. But the attacker would have to intercept the redirect to be able to impersonate a client. Without controlling the target domain this is not easily possible, especially if TLS is used, too. – Mitar Feb 23 at 8:49
  • No, impersonating a public client is really simple. You just create an authorization request (containing the client id) and send it to the authorization server. Then you do whatever you need to do to allow an authorization (logging in, clicking ok, stuff like that). You then block the authorization response from reaching the client (it's your browser, you can do that). Then you manually do a token request (with the client_id, but without credentials as it's a public client). Then you have a valid access token. You can't impersonate another user. But you've successfully impersonated a client. – BenjaminH Feb 23 at 9:17
  • I'm talking about a client in the sense of OAuth, you probably mean impersonating the web application that is registered at the Authorization Server as a client. – BenjaminH Feb 23 at 9:25
  • 1
    I see. If the logic requires knowing if it is really the client who is contacting the resource server. But I somehow never assume that because I cannot have that assumption on the frontend, so if the frontend already is able to talk to the API with PKCE, why not also the backend. – Mitar Feb 23 at 18:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.