State parameter and user redirection

First of all, your documentation has improved a lot over the years. Thank you for that.
My questions are about the state parameter and the redirection once logged in (not the callback from Auth0).

Classic use case:

  1. A client tries to access to a forbidden page “/page” that throws the equivalent of a 401.
  2. The client gets redirected to Auth0
  3. Once authenticated in Auth0, the clients gets redirected to the redirectUrl with the code.
  4. The server communicates with Auth0 and validates the token, etc.
  5. But now I want to redirect the user to the original page “/page”

So from the current documentation:

Link 1: https://auth0.com/docs/protocols/oauth2/oauth-state
tells us to use the state parameter. In this state, put a nonce and the returnUrl value.

Link 2: Redirect Users
does not mention state. Instead it tells us to store the returnUrl to be used after the authentication.

Link 3: https://github.com/auth0-samples/auth0-servlet-sso-sample
Seems to be an implementation following Link 1.
Here the code generates a state containing a nonce and the returnUrl.
It stores it as a session attribute before redirecting to Auth0 with the parameter state.
On the callback from Auth0 there is a validation of the nonce received against the one store, a validation of the URL (if it is in a whitelist from the configuration) and it finally redirects the client.

Question 1: So is the Link3 the recommended solution?

Question 2: In the Link 3, why do we need the pass the state actually. We already use the session attributes. Why not store the returnUrl directly and use it on callback?

Question 3: If I am the one generating and storing this returnUrl, I guess I do not need this whitelist. The nonce validation should be enough no?

(Q1) I’m not overly familiar with that sample, but if it follows the option described in your first link it is acceptable. I have a hard time in providing definitive recommendation myself because what it’s optimal for scenario A may not be for scenario B so depending on how you use them both the option on including the URL in the state itself and including the URL on session and then using it seem fine.

The real definitive recommendations around this situation are (in my opinion):

  • you need to protect your OAuth redirection endpoint against CSRF attacks (usually done through the random value present in state and then validating that the received state matches the one the current session expects.
  • you need to validate any data that can be provided/modified by end-users.

(Q2) If you prefer to store the final redirection URL in session then you just need to verify the state so that you know the current response is associated with that URL. As you said you, in this manner you don’t need to include the URL in state.

(Q3) If the source of the final redirection URL is server-side storage which an end-user cannot modify/control in some way then you can implicitly trust it and perform no additional validation.


Personally, I would tend to consider the approach where you generate state from random data coming from a cryptographically secure pseudo-random number generator and then also include the final redirection URL to create a composed value. In addition, you could hash the complete representation of the state and associate the hash to the current session (for a regular web application could be done through a secure HTTP-Only cookie so you would not even have to technically keep anything on server-side storage). Upon receiving the response you would again hash the received state, validate that it matches the one associated with the current session and proceed to use the return URL. Have in mind that with a simple hash anyone that can access and control secure HTTP-Only cookies can modify both the hash and the state. You could upgrade from a simple hash to a keyed hash (MAC) to ensure that no one besides your server-side could have generated the values.

All of the above seems a bit to much when compared to just store the URL server-side and don’t let anyone know/control it, but you do get the nice benefit of not actually having to store per transaction state on your server-side which is a nice thing considering that this transaction state can be created by non-authenticated users .

1 Like

Nice answer! Thank you for taking the time to answer each question and to explain the HTTP-Only cookie alternative.

Nice answer! Thank you for taking the time to answer each question and to explain the HTTP-Only cookie alternative.