How to use OAuth 2.0 “state” parameter other than CSRF protection

Ryo Ito(@ritou)
3 min readFeb 4, 2020

--

In RFC6749, the state parameter is defined for CSRF Protection.

The parameter SHOULD be used for preventing
cross-site request forgery as described in Section 10.12.

The client implementation required to prevent CSRF is as follows.

  1. The client generates a random string and associates it with the current session
  2. The client makes an “Authorization Request” containing that value as the state parameter and sends the User-Agent to the Authorization Server
  3. After user authentication and consent, the Authorization Server generates an “Authorization Response” containing that value and sends the User-Agent back to the client
  4. Client verifies that the returned state parameter is associated with the current session

This is very common sense for OAuth 2.0 clients.

On the other hand, in “the OAuth 2.0 Security Best Current Practice” whose specifications are currently being developed by the IETF OAuth WG, PKCE is also used for CSRF protection, and state may be used for “the original purpose”.

Clients MUST prevent CSRF. One-time use CSRF tokens carried in the state parameter, which are securely bound to the user agent, SHOULD be used for that purpose. If PKCE [RFC7636] is used by the client and the authorization server supports PKCE, clients MAY opt to not use state for CSRF protection, as such protection is provided by PKCE. In this case, state MAY be used again for its original purpose, namely transporting data about the application state of the client (see Section 4.7.1).

This article introduces two uses of the “state” parameter that are not CSRF protected.

The first is the “application state” that the client has in the session.
The application state here is information such as the redirect destination that the client performs after completing OAuth Dance.

For example, if you open multiple tabs of a web browser and use different functions of the same service for each, multiple reading and writing to the session will occur.
Most web frameworks should be fine, but a problem with handling keys when storing them in a session can affect the application state referenced after the authorization flow.
Clients can work around this problem by using the state parameter to store application state. However, encryption and signature protection are required to prevent tampering with query parameters. The BCP also mentions this usage

If state is used for carrying application state, and integrity of its contents is a concern, clients MUST protect state against tampering and swapping. This can be achieved by binding the contents of state to the browser session and/or signed/encrypted state values [I-D.bradley-oauth-jwt-encoded-state].

Another idea is to use the state parameter as a value to verify that the application state stored in the session is correct.

In this usage, the Client stores the application state in the session.
The Client generates a state parameter from the Application state when generating an authorization request and validates it when processing an authorization response.
If they do not match, the state parameter may have been tampered with, or the value of the Client session may have changed.
In this case, it is necessary to perform error handling without using the application state stored in the session. This will avoid confusion for the user due to unintended behavior.

NOTE: The content and structure of the application state depends on the client implementation.Therefore, Client needs logic to generate a character string corresponding to the value using a hash function or the like.

Application state handling is not described in the current OAuth 2.0 specification, but it is very important in implementing applications.
If you have any other ideas, please let me know.

--

--

Ryo Ito(@ritou)
Ryo Ito(@ritou)

Written by Ryo Ito(@ritou)

Developer for Digital Identity(OIDC, OAuth, WebAuthn, JWT…)

No responses yet