Cors On OAuth Token Endpoint NOT A BCP
Cors on OAuth Token Endpoint Not A BCP
Tuesday 4D
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.