The openid connect specification adds a nonce parameter to the authorize endpoint, which must be echoed back as a claim in the id_token. It claims that the purpose of this parameter is to prevent replay attacks and has some implementation suggestions around using http only cookies.
I understand what replay attack is in general, but I'd like to get a better understanding of the details of what a replay attack this might protect against might look like, so I can have a better idea about whether I have implemented it effectively, or made some subtle mistake.
I assume the replay attack is against the authorize endpoint, for some third party to get a token corresponding to a different user. Is that it or is it something else? What level of information do we expect the attacker has to replay? Do they have the traffic between the user agent and authorization server but not the client application, which is why they'd be able to replay the traffic to the authorize endpoint but would not be able to replay previous a cookie to the client application? Or they have the browser history of both but not the network traffic so they don't have old cookie values? Does it matter whether or not the user agent still has the previous user's session with the authorization server when the replay occurs? If the previous user does have a valid session with the authorization server and the attacker has access to that, can't they get access to a token without doing a replay? If they don't have a valid session with the authorization server, won't the user be prompted anyway, even if they replay an old request? If the user will be prompted to authenticate, presumably with credentials they don't have, what's the danger of a replay?
I have done a lot of searching and there are some similar questions (Replay attack example for validating nonce? and Purpose of nonce validation in OpenID Connect implicit flow) neither of these actually answers the question about how does this specific replay attack work. The first just quotes the recommended implementation form the spec, then talks about leaked tokens, which seems different from a replay attack to me (if the attacker has a leaked token, haven't they already won anyway?). The second explains the general idea of a replay attack, but doesn't talk about how this particular attack actually works.
As some background I'm making an openid connect app using the authorization code flow (so replaying the redirect from the AS to my app shouldn't do anything because you can only exchange the same authorization code for a token once AFAICT, so you would need to replay the authorize endpoint as well for a replay attack to be meaningful.) My app is using tokens I get back as bearer tokens to authenticate requests to my web server, and they are the entirety of the session state, there is no other meaningful session state or locally managed identity to tie the tokens to. My openid connect provider requires a nonce because it's a security best practice. Is it actually useful in my particular use case? Is the reason I'm so confused because doesn't actually provide meaningful protection for the particular thing that I'm doing? If this does have security implications for me I 110% want to make sure I do the right thing but I'm having a very hard time understanding what it protects me against.
Some implementation detail questions I'm fuzzy on due to not understanding the threat vector exactly:
- Do I validate the nonce matches what was sent to the authorize endpoint after pulling it back from the token endpoint and then assume it's good for the session? Or should validating the id_token cookie against the nonce cookie be part of every request just like checking the signature?
- The nonce is supposed to be tied to the session but the term nonce implies it should only be used once. If I need to send a user with a valid session back through the authorize endpoint for some reason (get a new id_token with an expiration further in the future? Request a wider set of scopes?) do I create a new nonce? Is it one nonce per session or per call to authorize?