State Parameter

Authorization protocols provide a state parameter. During authentication, the application sends this parameter in the authorization request, and the Authorization Server (Auth0) will return this parameter unchanged in the response.

Your application can use this parameter in order to:

  • Make sure that the response belongs to a request that was initiated by the same user. Therefore, state helps mitigate CSRF attacks.

  • Restore the previous state of your application.

Format and Limitations

For the most basic cases the state parameter should be a nonce.

This field can also be a Base64 encoded JSON object that can hold multiple values, such as a return URL.

Note that the allowed length for state is not unlimited. If you get the error 414 Request-URI Too Large try a smaller value.

How to use the parameter against CSRF attacks

A CSRF attack can occur when a malicious program causes a user's web browser to perform an unwanted action on a trusted site that the user is currently authenticated. This type of attack specifically target state-changing requests to initiate a type of action instead of getting user data because the attacker has no way to see the response of the forged request.

Diagram of CSRF attack

By using the state parameter to hold a value for verification, malicious requests can be denied.

Depending on the application type or framework this may be included for the developer. Also the exact structure of the requests may differ.

  1. Before redirecting a request to the IdP, have the application generate a random string.
xyzABC123
  1. Save this string to a variable in web storage.
auth0-authorize = xyzABC123
  1. Encode this value and set it as the state parameter in the request.
// Encode the String
var encodedString = Base64.encode(string);
tenant.auth0.com/authorize?...&state=encodedString
  1. After the request is sent, the user is redirected back to the application by Auth0. The state value will be included in this redirect. Note that depending on the type of connection used, this value might be in the body of the request or in the query string.
/login/callback?...&state=encodedString
  1. Decode the returned state value and compare it to the one you stored earlier. If the values match, then approve the request, else deny it.
// Decode the String
var decodedString = Base64.decode(encodedString);
if(decodedString == auth0-authorize) {
	// Authorized request
} else {
	// Request Denied
}

How to use the parameter to restore state

If a user intended to access a page in your app, and that action triggered the request to authenticate, once the user logs in you want to redirect the user to that page.

You can use the state parameter to restore the previous state of your application.

The process in order to do that, looks like the following:

  1. Store the URL value locally
  2. Authenticate the user
  3. If the authentication is successful, retrieve the value once you get the callback from Auth0
  4. Redirect the user to the page

How you store the URL value depends on your application's type. It can be local storage in single page apps or a cookie in a regular web app. Also, in this case, the parameter cannot be just a random string, it has to be a proper JSON object in order to hold values (see Format).

How to get the parameter value in a rule

You can access the state parameter value within a rule. How you can get this value, depends on the type of connection used; either from the body of the request or from the query string.

You can obtain it using the following:

var state = context.request.query.state || context.request.body.state;

Keep reading