1

Background: a traditional webapp with a server backend and 3rd party sign in. For this we get a validated id_token on our backend from the 3rd party, use that to identify an account in our system, and issue our own session cookie. We don't need access or refresh tokens from the 3rd party, and the front end doesn't need to see the id_token.

We are adding a new identity provider (Apple), and we have the option of using either:

  1. Authorization code flow (without PKCE) & token exchange on backend using client secret
  2. Implicit flow with response_mode=form_post, no token exchange, and we validate the id_token & nonce

The implicit flow seems as secure & more straightforward. Is there any reason I should use the code flow instead?

Note: Apple does not support PKCE. They also don't support the implicit flow, just the code & hybrid flows. Thus we would be using the hybrid flow here but ignoring the code, so treating it as if it's an implicit flow. Sorry, it's confusing.


Example

GET /authorize
  ?response_type=code id_token
  &response_mode=form_post
  &redirect_uri=my_url
  &state=the_state
  &nonce=the_nonce
  &scope=...
  &client_id=...

The callback sends the token directly to my backend

POST my_url
  ?id_token=the_token
  &code=ignored_code
  &state=the_state     

Additional information

Most recommendations I've found seem to recommend the authorization code flow with PKCE as being the most secure option because it keeps the tokens out of the url & browser history. However my understanding is that form_post also accomplishes that in a simpler way (assuming that you have a backend to process the request & use a nonce). Furthermore, I suspect because form_post is not universally applicable like code flow + pkce, that it is not discussed much, aside from these links I found:

  • Auth0 suggests using implicit + form_post flow is a good option

    This way you can have an optimized authentication flow (no need to exchange the code for an ID Token)

  • Mention of form post being simpler from openid foundation:

    To aid the implementation of the best practice, we recommend that OPs consider supporting OAuth 2.0 Form Post Response Mode, as it makes it simpler for clients doing code id_token to get both the code and the ID Token on the backend for verification.

  • In this draft document about OAuth security topics, using form_post is suggested a few times as a mitigation for some attacks. But in general it strongly recommends code flow with PKCE.
    • But if PKCE is not available, it doesn't mention what the next best thing is..
  • Specification for form post response mode
  • Without PKCE, state should be used to carry a nonce/one-time use token to defend against CSRF. (PKCE helps with more than just CSRF, yes) and the client (your app) should verify it. The BCP mentions this. – identigral Aug 15 at 20:45
2

I don't see any security advantage of using the authorization code flow in your case (traditional web application). Indeed, form_post is not vulnerable to referrer leaking or browser history leaking. Posting tokens is nothing new, it's how SAML2, the predecessor of OpenID Connect, worked well without bringing in any specific security weaknesses.

And form_post indeed avoids one round-trip to the AS to authenticate the user. It's just that it cannot be used with javascript SPAs or mobile applications.

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.