Subject: [OAUTH-WG] JWT compares client time with server time

From: Ben Bucksch <[email-masked]>
Date: Fri, 22 Jan 2016 01:03:53 +0100

Story: We wrote a script implementing JWT.

The code was working for my colleague, who wrote the script, but I just 
got "Invalid authentication credentials".

We were debugging it for days (!), suspecting shell argument passing and 
parsing, OS differences and what not. We compared credentials and 
confirmed they are identical. Still, the result was different. During 
debugging, once, by coincidence, it worked - at a time when it should be 
expired.

What was the reason? My clock on my computer was fast.

I was speechless. Client/server protocols must NEVER compare client 
clocks with server clocks, because clocks are very often off. Even if it 
was originally set exactly right by the second, clocks always have a 
drift in one way or another. If you have 5 million users, you will 
surely have 500000 whose clocks are off by 1 minute, and 50000 users 
whose clocks are off more than that.
In my case, my clock was 95 seconds fast. That's not uncommon. You 
cannot expect nor demand that every computer in the world runs NTP clients.

OAuth 2.0 knows that and does not rely on client clock matching server 
clock. For good reason. Ditto HTTP Cache headers don't send client time, 
even though that's an obvious and simple implementation, but the server 
sends and ETag and the client echos it back. Even if that's a more 
complex implementation, it's crucial to work reliably.

------------------------------------------------------------------------

Worse, in JWT, iat (time of issue, created by JWT client) is often 
enforced with second precision on the JWT server. A client clock that is 
just 3 seconds fast (very likely) will cause an iat in the future, which 
makes the server reject it.

You simply cannot compare client clock with server clocks. Please change 
the protocol to not do that, or take JWT off the proposed standards track.

---

From: Thomas Broyer <[email-masked]>
Date: Fri, 22 Jan 2016 16:05:08 +0000

Or just account for clock differences when comparing values, which I
believe is what the specs suggest.

Le ven. 22 janv. 2016 15:50, Ben Bucksch <[email-masked]> a écrit :

> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

---

From: John Bradley <[email-masked]>
Date: Fri, 22 Jan 2016 13:39:09 -0300

Sorry to hear about your debugging trouble.

JWT is a security token format, a bit like SAML.

It has “iat” (issued at) as one of the optional claims that a protocol can use.
It is defined similarly to IssueInstant in SAML.

It is the protocols that use JWT that need to define the comparison rules, the value is what it is, and a receiver needs to  accommodate clock drift in both cases.

OAuth is just starting to define a JWT access token for PoP.  https://tools.ietf.org/html/draft-ietf-oauth-pop-key-distribution
That has iat in the example but nothing calling it out in the validation rules at the RS.   That is something I will note.

OpenID Connect defines the use of iat in id_tokens

	• The iat Claim can be used to reject tokens that were issued too far away from the current time, limiting the amount of time that nonces need to be stored to prevent attacks. The acceptable range is Client specific.

In that case it is used to manage the cache for replay protection.

For exp we do note in Connect:
	• The current time MUST be before the time represented by the exp Claim (possibly allowing for some small leeway to account for clock skew).

It is not clear from your email what protocol you are trying to use JWT in.

At the JWT level we don’t know what a protocol is going to use iat for so specific advice on managing clock skew is difficult.

Regards
John B.

> On Jan 21, 2016, at 9:03 PM, Ben Bucksch <[email-masked]> wrote:
> 
> The code was working for my colleague, who wrote the script, but I just got "Invalid authentication credentials".
> 
> We were debugging it for days (!), suspecting shell argument passing and parsing, OS differences and what not. We compared credentials and confirmed they are identical. Still, the result was different. During debugging, once, by coincidence, it worked - at a time when it should be expired.
> 
> I was speechless. Client/server protocols must NEVER compare client clocks with server clocks, because clocks are very often off. Even if it was originally set exactly right by the second, clocks always have a drift in one way or another. If you have 5 million users, you will surely have 500000 whose clocks are off by 1 minute, and 50000 users whose clocks are off more than that.
> In my case, my clock was 95 seconds fast. That's not uncommon. You cannot expect nor demand that every computer in the world runs NTP clients.
> 
> OAuth 2.0 knows that and does not rely on client clock matching server clock. For good reason. Ditto HTTP Cache headers don't send client time, even though that's an obvious and simple implementation, but the server sends and ETag and the client echos it back. Even if that's a more complex implementation, it's crucial to work reliably.
> 
> Worse, in JWT, iat (time of issue, created by JWT client) is often enforced with second precision on the JWT server. A client clock that is just 3 seconds fast (very likely) will cause an iat in the future, which makes the server reject it.
> 
> You simply cannot compare client clock with server clocks. Please change the protocol to not do that, or take JWT off the proposed standards track.
>