Disclaimer: I know The OIDC implicit flow has been discouraged for a long time and I should use code flow on greenfields. Reasons include but are not limited to leakage of the authorization server redirect URL (via several means) essentially completely exposes the resource server access token. But I'm not asking whether or not I should use implicit flow.
There seems to be a lot of confusion (including by yours truly) about exactly what the OIDC "nonce" parameter that is required in implicit flow is actually for (see 1, 2, 3). The spec is frustratingly vague (maybe intentionally), stating it's there to prevent client specific "replay attacks". Finding a real life concrete example of such an attack is illusive. After reading 1, 2, 3 it's still a bit unclear, but the only thing I can see nonce mitigating, given the required oAuth 2.0 CSRF mitigation (such as
state variable) is also implemented, is a replay by a MitM (the MitM can easily attach the state to a replayed response, but can't forge the nonce).
However, that is all in the scenario where the "client" is strictly interpreted as a public web app running in a user agent. In the specific case of a single page web app (SPWA) accessing its own trusted resource server (RS) via the access token, there seems to be an intuitively obvious use for the nonce in mitigating leakage of the response URL (and thus access token) if the nonce is generated server side (so in a sense the "client" is spread somewhat across a trusted backend and SPWA):
- The nonce is generated by the webserver serving the SPWA and stored in a HttpOnly cookie. The webserver and the API share some origin base domain so the HttpOnly cookie is passed between them (maybe they are even the same server).
- When the SPWA makes a request to the authorization server it adds a hash of the value in the cookie (the hash would need to be embedded in the SPWA code since it can't read the HttpOnly cookie).
- The nonce is embedded in the access token sent to the RS and verified by the RS.
Now the bearer token is not usable outside of a context that originated with a request to the webserver hosting the web app.
The problem is, A. OIDC spec never explicitly states the nonce should be embedded in the access token (AFAICT), and B. never explicitly describes such a scenario. However, the spec does allude to it, and even exactly the above scenario:
- A.5. Example using response_type=code token shows a nonce being sent with a
response_type=code tokenrequest in which no id token is returned (so what else is the nonce for ..). Keycloak, for one implementation, does embed the nonce in the access token as well as the id token.
- 15.5.2. Nonce Implementation Notes suggests ".. to store a cryptographically random value as an HttpOnly session cookie and use a cryptographic hash of the value as the nonce parameter.". Well, only a server can read or write a HttpOnly cookie, so this advice is completely useless if the "client" is strictly considered the SPWA.
So questions are, am I missing something or is this a legit way of using the nonce? Can I interpret the vague language in the OIDC spec as permitting such use?