PKCE: What and Why
dropbox.tech
dropbox.tech
> OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack. This specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key for Code Exchange (PKCE, pronounced "pixy").
While losing a client secret to an attacker is obviously worse, because it allows for repeated grant requests, losing an access token can be bad too.
So, be aware of both things when you are running in a client like a browser or mobile application which can't be trusted to keep a secret. You can try to minimize the risk by using a HttpOnly cookie for the browser or secure storage (keychain, etc) on a mobile app, as well as keeping your token lifetimes short.
Disclosure: I work for an IDaaS provider.
Just seems fundamentally more secure.
For example we have configured our implementation of OpenID Connect to use PKCE for retrieving an authorization code, and then when calling the token endpoint, requires that the the client authenticate using a client_assertion JWT (as detailed in https://tools.ietf.org/html/rfc7523#section-2.2)
This can be combined with registering a custom scheme handler and thus hijack the redirect URL. If you're able to register your app as a handler for "airbnb://", then your app will be opened once the service redirects back. And if you've figured out the client secret then you can finalize the authorization step and get an access token.
The difference in PKCE is that the client generates a unique random secret (code verifier) before it starts everything. The authorization is then coupled to the hash of the secret (code challenge), and for the authorization code to be converted into an access token the client needs to reveal the original code verifier.
This part of the premise didn't make sense to me, and especially people opting for implicit as an alternative instead, because it still has this 'intercept' problem, except instead of a 1-time code, you get a long lived access token.
We start using the language "public client" and "private client", where a public client is an OAuth client like a mobile app or SPA that does not have a client secret, but has an access token delegated to it(+optional refresh token). Public clients must use implicit+PKCE.
Private clients are what we would have previously thought of as an Authorization code grant client where a server process has an access token to take actions on behalf of a user.
Depending on the OAuth use case, maintainers of the system may need to keep track of what clients are public or private, and limit their entitlements accordingly.
Public clients have the obvious issue that they're on an end-user device and thus the tokens may be stolen, proposed standards like JWT DPOP [2] and token binding [3] aim to address this.
[2] https://datatracker.ietf.org/doc/draft-ietf-oauth-dpop/
[3] https://tools.ietf.org/html/rfc8471 . Though I should say token binding does seem like it will never go anywhere.
This space is insane and hard to keep up with.