It occurred to me that we might not have to do “round-trip nonces” at all between a Relying Party and the LID site to prevent replay attacks.
The following one-directional protocol seems to be sufficient (using our patient Mr. LID Demo User and FirstSSO Inc. as an example, as always)
- The challenger (e.g. the LID Relying Party) sends a redirect to the LID, such as:
http://lid.netmesh.org/liddemouser/
?lid-action=sso-approve
&lid-target=http://firstsso.netmesh.org/infogrid-php/
without specifying a nonce. - If the LID site successfully validates the browser session, the user gets redirected to the following URL:
http://firstsso.netmesh.org/infogrid-php/
?lid=http://lid.netmesh.org/liddemouser/
&lid-nonce=NNN
&lid-credtype=gpg%20--clearsign
&lid-credential=CCC
whereCCC
is the appropriate signature on the URL, andNNN
is nothing else than a current time stamp according to the LID site’s clock, in some suitable encoding. - The Relying Party (e.g. FirstSSO) now performs the following algorithm:
- Check whether the signature is valid on the request, and corresponds to the LID that was provided in the request. If not → access denied.
- Check the provided nonce NNN. If not present → access denied.
- Calculate the delta time between the current time (as measured by its own clock) and NNN.
- If the delta is outside of a defined time window → access denied. The time window could be something like “nonce issued not longer than 6 hours ago according to local clock, and no more than 1 hour in the future”. The time window’s parameters are not critical for this algorithm; the size of the time window is determined by the maximum clock skew a party is willing to tolerate.
- Check whether this nonce has been used by the given LID during the past 6 hours (whatever the boundary of the time window). If it has been used before with this LID → this is a replay attack, access denied.
As an attacker, I thus cannot successfully replay any request that I have observed. If the observed request was made in the recent past, its nonce will still be in the database and access will be denied. If it was made in the more distant past, it will be rejected because it is too old. And while the nonce is predictable (the current time), I cannot construct a URL myself because that would require me to fake the signature on the URL and thus to break GPG.
As a Relying Party, I will have to keep track of all nonces used within the time window, but I think that is a manageable task. The size of the required store is determined by the maximum clock skew I’m willing to tolerate and how often I invalidate my own session cookies and request a new signature from the LID site, so the relying party can put the trade off where it likes to.
Special thanks to Dick Hardt of SXIP, who recommended that we should tighten our use of nonces during OSCON to better protect against replay attacks.