OpenID Connect - State and Nonce
Authentication
What is authentication? It is the process by which we let a user prove to the application their identity. This is commonly done by means of a username and password. Username is the identifier that represents the user in the application.
Most applications today follow what is called the OpenID Connect authentication flow. This is defined by the OpenID Foundation and is a derivation of the OAuth 2.0 specification.
The OpenID Connect flow involves a set of requests between the application where the user wants to login and server where the user’s identity is registered. This server which stores the user’s identity is typically called a Identity Provider or IdP. The OpenID Connect flow defines various endpoints on the IdP which are used to perform various actions during authentication. The flow starts by sending a request to the authoriation_endpoint with a certain set of parameters which are chosen by the application to convey to the IdP what things are needed for the context. There are a standard set of parameters defined in the specification. In most cases everything that we need using these parameters. If we look at the possible parameters, we will find about two very interesting parameters - state and nonce.
State
state is the most fundamental one that isn’t used to identify a user but used to ensure various security guarantees. Since the authentication flow happens in a browser, anu yser can start the flow. It may so happen that the application never wanted a authentication flow. To ensure that a state parameter is used to ensure that it is something that the application issued for a request flow to start. This way a random state value will essentially get rejected later down the request flow. Let me explain this by an example.
- Some rogue actor starts the login flow by making a request to the
authorization_endpointon the IdP - The IdP will redirect the rogue actor to enter the credentials.
- The rogue actor now copies the browser request in (2) and copies it over to the victim’s browser where he sees to enter the credential. This is tricking the victim to enter credentials for a flow which neither the victim nor the application started.
- Let’s say the victim entered the credentials, the IdP will eventually redirect back to a
callbackurl on the application. - The
callbackrequest always has thestateparameter. Since in this example thestatewas created by the rogue actor, the application is unaware of thestatevalue. - The application will reject the data that is being provided to it on the
callbackurl and thus we have aborted a rogue actor from initiating a request without the knowledge of the application.
Nonce
nonce or n once is something that is often skipped when performing a authentication flow. During the authentication flow the application has ensured that the request flow was started by the application using the state parameter. But how we ensure that the authorization code grant that was returned to it by the IdP was for the same flow that it started. This is provided by nonce. In other terms we are trying to ensure that a authorization code grant that was returned to the application in a callback flow cannot be easily changed. Let me explain this with an example -
- Lets say the user wanted to perform some action on the application which needed authentication.
- The application would redirect to the IdP with a valid
statevalue. - Now the rogue actor completes another authentication request with the login parameters that it wants and then add the
authorization code grantin the callback url along side thestateparameter. - Since
stateis a valid value, the server will not reject theauthorization code grantright away. Did the attacker succeed? - No, the application also passed along
noncein the initial authorization request. So when theauthorization code grantis exchanged for aaccess tokenandid tokenit gets back thenoncethat was requested in the original login flow. Thisnonceis embedded in theid tokenreturned by the IdP. - So if the
nonceassociated with a certainstatevalue isn’t the same as thenoncereturned in theid tokenthe callback flow halts and nothing is processed. - Again rogue actor stopped!
In other words nonce is used to stop authorization code grant injection attacks.