Intercepting OAuth Authorization Code without PKCE

Viewed 413

A system where I work is set up to authenticate users of a single page app (with a backend) via an OAuth Authorization code grant, without PKCE.

So:

  1. User clicks login and is redirected to the auth server
  2. User authenticates, and gets redirected back to the callback url with an authorization code
  3. The client sends the authorization code to a public endpoint on our backend
  4. The backend endpoint supplies a client id and secret, along with the authorization code in exchange for an access token & refresh token, then it returns them to the client in the response.
  5. The client can now make authenticated requests to our API using the access token

As the endpoint in step 3 is publicly accessible, what is to stop an attacker from intercepting the authorisation code and sending a request via postman to the endpoint so that they receive the token instead of our client?

My understanding is that this is why the PKCE extension is now recommended but I'm far from an expert.

As the public endpoint adds in the client secret, it's similar to the authorization server not asking for a client secret at all. Anyone can call the endpoint with a code and have it pass the code + secret to the authorisation server.

Is that a vulnerability or am I worrying about nothing? If not, then why does OAuth require a client_secret at all for an Authorization code grant?

Thank you!

1 Answers

It's good to stick to the standard flows and recommended practices. If you create your own flow (as the one from your work), it's up to you to assess security risks. In general, the more complicated you make it, the more vulnerable it gets.

So I would rather stay with the basic auth code flow initiated by your backend and redirected to your backend directly (consider using it with a backend session or a HTTP-only cookie with a token). In this scenario, using PKCE is optional, but if you can use it, it could improve the security level.

Or I would use the SPA as an OAuth2 client using auth code flow with PKCE without involving your backend. The backend would have a role of a resource server.

You probably use a secured connection to your OAuth2 server. In your current implementation, the weak point is a browser. So if you are concerned about the auth code being stolen, change the flow to the standard auth code flow with the backend as an OAuth2 client. But it's good to know that OAuth2 server should revoke already issued tokens if it receives another /token request with the same auth code (assuming one of the requests was from an attacker).

Related