Cors On OAuth Token Endpoint NOT A BCP
Cors on OAuth Token Endpoint Not A BCP
Convener(s): Travis Spencer, Curity
Notes-taker(s): Travis Spencer
Tags for the session - technology discussed/ideas considered:
oauth, bcp, spa
Discussion notes, key understandings, outstanding questions, observations, and, if appropriate to this discussion: action items, next steps:
The Best Common Practice (BCP) for use of OAuth with Single-page Applications (SPA) is being discussed and put forward as a formal recommendation. The use of the implicit flow is being discouraged, and, in its place, the use of the code flow with a public client that uses Proof Key for Code Exchange (PKCE) is being set forth. This BCP is inline with the same advice given for public, mobile clients. However, there are some issues with this that were discussed:
1. The token endpoint is really many endpoints, meaning it has a lot of complex logic and handling in it to deal with the tunneling of different requests types.
2. This complexity is exacerbated by the fact that many clients with many different client authentication methods access this endpoint.
3. If CORS support is added to this, the logic of the token endpoint will be very hard to maintain, and easy to get wrong. How can this be a BCP? The concern is that incorrect issuance of tokens will often be done with SPAs which are public.
4. Because the code flow uses two endpoints, there is the possibility of token endpoint mixup attacks which the implicit flow (or a new protocol like the assisted token flow) do not suffer from.
These issues were perceived as problems that made the use of the code flow with public SPA not something that should be considered a BCP.
This was discussed and decided not be a problem because:
1. The logic and switching to handle various message exchange patterns at the token endpoint will never go away. This isn't a reason to add more and make the logic more complex, but it is not exacerbated by the use of code flow with SPAs because the interaction with public clients already exists if mobile, public clients are supported.
2. CORS does not need to be used; it should be effectively switched off by always returned "*" for the Access-Control-Allowed-Origin response header. The reason being that other public clients, like mobile ones, don't sent an Origin header, so it isn't changing the security posture of the AS/OP. The Origin header can also be stripped off by a back-end of the SPA's making it a non-CORS request even though the client is still public. So, the browser's effort to provide additional security is not adding anything, even an extra defense in depth. So, strangely as it may sound, the BCP is actually to make the browser's use of CORS not applicable.
3. The SPA is actually not making unauthenticated calls to the token endpoint. It is being authenticated using the PKCE verifier. If some other application were to make the same request, it would need the proof key which the SPA would have to provide it. If the SPA, however, keeps the proof key secret, only it will be able to redeem the code. This will protect against CSRF, for example.
4. The endpoint mixup is a low risk because the call to the token endpoint doesn't happen as a result of a redirect. Instead, it's based on configuration of the client. This is usually metadata driven, so the ways to perpetrate this attack is if the AS/OP's metadata is poisoned, the client is misconfigured, or other low-risk vectors.
For all these reasons, the code flow with PKCE for SPAs is actually OK and can can be considered a BCP.