Node-jsonwebtoken: nbf + clockTolerance cause issues

Created on 2 Jun 2018  路  5Comments  路  Source: auth0/node-jsonwebtoken

https://github.com/auth0/node-jsonwebtoken/blob/73c4a5ac45d557ef0dc1c43fcae6b7fc9bc3f19e/verify.js#L116

The clockTolerance may be wrong when used together with nbf.
When the token has just been issued if added with clockTolerance it'll always fail I guess.

I'm pretty sure it should extend exp (expiration) time and shorten nbf (not before) time.

I can submit a PR if someone agrees.

Most helpful comment

I agree with @MitMaro as after reviewing the code again I could figure the logic was fine.

Still I could only get rid of the issues with tokens failing on another server (right after its creation) disabling the nbf completelly

jwt({ignoreNotBefore: true});

All 5 comments

Can you provide an example of when the clockTolerance is wrong?

Assuming the current time is 1000, and providing that options.clockTolerance = 3. When the token has just been issued it will have payload.nbf = 1000. If you attempt to verify immediately The current clockTimestamp = 1000. Given these values you end up with 1000 > 1000 + 3 which would be false. Since the token should be used after the nbf timestamp, this is a valid result. If instead the clock tolerance was shortened, you would have 1000 > 1000 - 3 which would result in a valid token being rejected.

Please consider this timeline as the normal condition valid jwt

----------------------------------------------------
nbf               valid usage            exp

What the clockTolerance does it to increase the valid usage lifetime.
I'm my understanding it would be more assertive to increase to both ends of this timeframe.

What the system currently does is dislocate the valid usage.

    ----------------------------------------------------
nbf+tolerance       valid usage          exp+tolerance

This is moving the valid usage to the right - it does not increase it. That works for expiration. But if a token is used right after creation then nbf will fail. Say nbf=1000 and at the same time we validate it: (payload.nbf > 1000+tolerance) == false

I have this scenario currently when my frontend regenerates the token on failure, to sequentially try the same api endpoint again. node-jsonwebtoken is failing due to the clockTolerance.

It seems to me a clockTolerance implementation should increase both ends of the valid time, or at minimum just increase the expiration.

------------------------------------------------------------
nbf-tolerance       valid usage      exp+tolerance

I think there must be some confusion, as it already does exactly what you are looking for, at least from understanding.

Assuming the payload, {"exp": 1100, "nbf": 1000} with the current time being 1000, and a clock tolerance of 10 .

The nbf is verified using:

if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) {
    return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000)));
}

would result in:

if (1000 > 1000 + 10)) {
    return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000)));
}

This would be false, the error will not be returned, and the token would be valid.

I think there must be some other issue with the tokens.

I have this scenario currently when my frontend regenerates the token on failure, to sequentially try the same api endpoint again. node-jsonwebtoken is failing due to the clockTolerance.

Let me write the cases I can think of:

A) Clock timestamp => Frontend: 995 and API: 1000. Clock Tolerance: 10
Check: nbf=995 > clockTimestamp=1000 + clockTolerance=10 => false, all good
Since the verifier is "in the future" from the signer point of view there will be never a fail here.

B) Clock timestamp => Frontend: 1000 and API: 995. Clock Tolerance: 10
Check: nbf=1000 > clockTimestamp=995 + clockTolerance=10 => false, all good
Since the verifier is "in the past" from the signer point of view here the tolerance matters, it needs to be well defined.

B.2) Clock timestamp => Frontend: 1000 and API: 985. Clock Tolerance: 10
Check: nbf=1000 > clockTimestamp=985 + clockTolerance=10 => true, failure.
Clock tolerance should be greater.

C) Clock timestamp => Frontend: 1000 and API: 1000. Clock Tolerance: 10
Check: nbf=1000 > clockTimestamp=1000 + clockTolerance=10 => false, all good

Can you think in any other? Did I miss anything?

I agree with @MitMaro as after reviewing the code again I could figure the logic was fine.

Still I could only get rid of the issues with tokens failing on another server (right after its creation) disabling the nbf completelly

jwt({ignoreNotBefore: true});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

cope picture cope  路  4Comments

salali picture salali  路  5Comments

usamamashkoor picture usamamashkoor  路  4Comments

yvele picture yvele  路  4Comments

BarukhOr picture BarukhOr  路  4Comments