angular-auth-oidc-client icon indicating copy to clipboard operation
angular-auth-oidc-client copied to clipboard

[Bug]: Token doesn't get validated due to a clock skew

Open TamaraMilanov opened this issue 2 years ago • 3 comments

Version

12.03

Please provide the exception or error you saw

The problem happens when the client time (the clock) is not synchronized with the server time or better said real-time. When client time is out of sync more than 2 minutes the issue happens.

I have tried to extend the TokenValidationService and override the validateIdTokenIatMaxOffset() method, but this is not possible due to the bug reported here: https://github.com/damienbod/angular-auth-oidc-client/issues/1370

Also, increasing the value of maxIdTokenIatOffsetAllowedInSeconds would not be a solution, since we don't know how much the client clock could be out of the sync.

Steps to reproduce the behavior

Change the client time to be for example 5 minutes backwards or ahead of the real-time.

A clear and concise description of what you expected to happen.

Since it is impossible to force every client to turn on the system time sync on their devices, would it be possible to use the server time instead of the client time to calculate the diff between the current time and the iat token time?

validateIdTokenIatMaxOffset(dataIdToken, maxOffsetAllowedInSeconds, disableIatOffsetValidation, configId) {
        if (disableIatOffsetValidation) {
            return true;
        }
        if (!dataIdToken.hasOwnProperty('iat')) {
            return false;
        }
        const dateTimeIatIdToken = new Date(0); // The 0 here is the key, which sets the date to the epoch
        dateTimeIatIdToken.setUTCSeconds(dataIdToken.iat);
        maxOffsetAllowedInSeconds = maxOffsetAllowedInSeconds || 0;
        const nowInUtc = new Date(new Date().toUTCString());
        const diff = nowInUtc.valueOf() - dateTimeIatIdToken.valueOf();
        const maxOffsetAllowedInMilliseconds = maxOffsetAllowedInSeconds * 1000;
        this.loggerService.logDebug(configId, `validate id token iat max offset ${diff} < ${maxOffsetAllowedInMilliseconds}`);
        if (diff > 0) {
            return diff < maxOffsetAllowedInMilliseconds;
        }
        return -diff < maxOffsetAllowedInMilliseconds;
    }

TamaraMilanov avatar Jul 11 '23 10:07 TamaraMilanov

That's not an error, that's a security feature. If you cannot guarantee the client has an accurate time, many defences against replay attacks are gone.

As a practical solution to your conundrum, you can set the maxIdTokenIatOffsetAllowedInSeconds to 300 (five minutes) instead of the default 120 (two minutes).

This is the recommended value for Kerberos (which serves an authentication role similar to OAuth). Additionally it is unlikely that people are even capable of browsing the web when their clock view exceeds such values, because HTTPS websites stop working as TLS encrypted connections cannot be established.

EDIT: Actually the TLS protocol doesn't put any hard demands on clock skew limits, so it must be defined at an application (maybe browser) level.

Ghostbird avatar Sep 20 '23 12:09 Ghostbird

Obviously using the server time is not an option when you use the time offset to defend against replay attacks.

Ghostbird avatar Sep 20 '23 12:09 Ghostbird