-
Notifications
You must be signed in to change notification settings - Fork 692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clock skew is in wrong direction #1135
Comments
I agree with all the issues raised above.
I also think this is a bug since I do not see a reason why 0 would be an invalid value for the clock skew. |
Im new to OAuth in my applications, but isnt this a serious issue? How can I determine if a user is authenticated if not by |
Yeah, I'm surprised this hasn't been fixed yet. I ended up writing my own short method for checking whether access token is expired: private get isAccessTokenExpired() {
// custom check of token expiration to avoid bug in library: https://github.com/manfredsteyer/angular-oauth2-oidc/issues/1135
const expiresAt = this.oAuthService.getAccessTokenExpiration() as number | null; // can return null https://github.com/manfredsteyer/angular-oauth2-oidc/blob/12.1/projects/lib/src/oauth-service.ts#L2354
return Date.now() > (expiresAt ?? 0) - (this.oAuthService.clockSkewInSec ?? 0);
} |
why has this bug not been fixed so far? Because nobody created a PR? Or does somebody have reservations about fixing this?! |
I've wasted sooooo much time trying to figure out why sometimes I was logged out with no reason. This is a MAJOR bug, please fix it as soon as possible. |
If the "skew" is like a token response flight time, the sign must be definitely "+". Expired condition:
|
I have run into a similar problem with this variable being used wrongly. angular-oauth2-oidc/projects/lib/src/oauth-service.ts Lines 2266 to 2267 in d95d7da
It first checks for the issued at time - clockskew, then for the expired at time + the clock skew, and throws a 'Token expired exception'. There is more than one problem between those lines. It tries to do two different checks at once, and both of them are incomplete. Yes, if the expired at time + the clock skew is greater than the current time, the token is really expired. But what is really needed is to check if the issued at time + the clock skew is greater than the current time, so that we can know if the computer time is off. If the computer time is off, the token expiration is still wrong, but we will just notice it later. Also, this check explained above only checks the ID token, but the access token never get checked like that, which is also weird. |
A problem that we face is that if you the client's system time is not in sync the users will run into a never ending loop. I know it's possible to provide a custom date-time-service - https://github.com/manfredsteyer/angular-oauth2-oidc/blob/2c0d16bbe20136cfbd3ebc6babdc49dac1aa7d78/docs-src/custom-date-time-provider.md Another idea is to implement an HTTP-call to get the current time from a date service or the token-issuer inside of the custom date-time-provider. But would be an overheader as this value is already part of the HTTP-responses of the id-provider. I'm wondering if this value is accessible inside of the now()-function of the date-time-provider... |
💡 EDIT: This comment is specifically meant as a reply to the one immediately above, sharing my thoughts about the suggestion to get the "current time" / clock in the library from an HTTP Header or via an API Call from a server. It's not so much about the bug with the clock skew feature. Thx for the additional insights @LordMidi. You pose some interesting ideas. I do think if you want to implement those I recommend using a custom date-time service to do so, and I would caution strongly against it. Security features like these rely on both parties having a decently accurate clock on their ends. They prevent tampering with data by folks in the middle or otherwise compromised setups. If you ask the server (via a header or an api) for "the current time" to do checks on tokens, you give away some control over security. Of course the bug with clock skew needs to be fixed at some point, because some "bandwidth"/skew will in practice happen. But apart from that I think the check is good as is. If you cannot rely on accurate clocks it is perhaps better to completely turn off these security features (e.g. via a custom datetime provider) as opposed to relying on another party for providing time to your app. In short: if you want to use your suggestion as a workaround, because you understand the security implications, I'd say "go for it", using the existing escape hatches. But I'd be weary to add features to the library of the sort. Hope that makes sense? |
I'm sorry, are we talking about the same thing? What check is good as is? It's not only a security check, since you need to check when the token expires. The check clearly doesn't work as expected. It has many issues, as described above. Of course, you may have a different idea about how to use the library "correctly", but it's completely fair to ask for a proper clock skew check. And it feels a bit degrading, when you say it's all good as is. |
Ah, sorry for the confusion @BarsikV. The feature is certainly bugged at the moment, as indicated by the various replies in this issue. I didn't mean to say that "all is well". Instead, I was specifically responding to the comment above mine. Getting the "current time" from an API or a HTTP header is not the way to go, I meant. I'll edit my previous comment to make that clearer. |
@jeroenheijmans ok, it was a bit confusing, sorry, and thanks for clarifying. |
Sorry If I messed things up here. We just have this problem now and got the token expired error and I thought our "research" could help in the overall context. And this is the only thread I found which is active and seems to have a similar cause for the error to occur. Thanks for your answers @jeroenheijmans we will try consider your comment. |
Perhaps there is a misunderstanding, but IMHO the code does what it is supposed to do: Making the token be valid a bit longer b/c clocks might be not in sync. This is how the check works:
|
As some time has went by and we went into deeper researches we identified the client time as the source of error for us. If the users local time is completely out of sync validation of the token fails (of course). The only bullet proof solution would be getting the current time from the server that issued the token to use this for validation. But we decided to show a error message instead. |
Maybe I'm just missing the use case of that. I figured the intend would be to consider it invalid a bit earlier, because clocks might not be in sync.
And then there's also the issue that setting clockSkew to 0 actually makes the default 10 minutes be used instead. (this might have been fixed, I haven't checked) |
Hi @Shne, ah, I see. I did have this in mind when adding the skew. I think, for this use case, you could set it to a negative value. I also check for 0 in the next version (will land soon) so that setting it to 0 works. |
Hi @manfredsteyer, thanks for taking the time to look at this.
As described in the original post:
But maybe that is also changing in the next version? |
I agree. This can be abused, and potentially a lot of harm could be done in 10 minutes. I think the sensible default value is below 30 seconds. It is especially important to mention this default value in the documentation, because it may be surprising for library consumers to see their tokens valid for 10 minutes after they should have expired. |
Hi @Shne, ah, I see. I could add an optional property Best wishes, |
@pKrupaJunior - yes, that's a good point. I'm a bit afraid of changing it now. Let's spread the word via the docu. |
Just added the new Feel free to reopen this issue if this doesn't solve the situation for you. |
This is exactly the issue. The token is considered valid when it shouldn't because it is expired. I don't get it why this should be ok in any case!? If the token is within the clockSkew but already expired, the Angular application will happily use it / not perform a new login and the calls fail. |
@rasifix If the client's time is not in sync with the current time he will always have an invalid token. For me, an idea of skew is to forgive small differences, to make it possible to work with such users (wrong time or slow internet). |
that is not the issue. if the client time is perfectly in sync, the token will be used even after effective expiry for another 10 minutes. Setting the clock skew to -10 minutes fixes the problem. The client will think the token is expired, even if it has not expired, but that is perfectly fine as we can simply login again and get a new token. |
When the client has an invalid time (more than the skew time - believe me there are a lot) the validation will always fail. So users with invalid time ended up in a loop in our application. Token invalid -> get new token -> Token invalid -> get new token -> ... |
@manfredsteyer decreaseExpirationBySec is declared as "number of seconds" but it takes part in calculations as milliseconds |
@manfredsteyer I'm sorry, but why hasn't this been fixed properly instead of adding optional parameters to work around an obvious bug? |
Just ran into this as well, |
i think this is still a bug as in the quoted comment |
Describe the bug
Unless the intent is to consider an access/id token valid for 10 minutes (by default) after it has expired, the clock skew calculation is in the wrong direction.
This, somewhat recent, commit seems to be the culprit: 68238fb#diff-685e26c24f3c008856834f8b4a350d5472b6aea01a623c31a8513f6cc599c57fR2391
The pluses should not have been changed to minuses.
It causes the current time to be considered 10 minutes (by default) in the past, causing the token to be considered valid for longer.
I.e.: with the current code, the current time needs to be 10 minutes after the token expiration time for the comparison to turn true and the return value (indicating validity of token) to become false.
Perhaps it could be worth refactoring this code for readability. At least, I had some difficulty understanding it.
Expected behavior
Tokens should be considered expired once they expire.
Versions
Library version 12.1.0
Additional context
I was experiencing problems with access tokens considered valid by the
hasValidAccessToken()
method, where I knew they were expired.I can't even use negative values to fix it, because of these lines: https://github.com/manfredsteyer/angular-oauth2-oidc/blob/12.1/projects/lib/src/oauth-service.ts#L2233 that will throw 'Token has expired' Errors if I use a reasonable, but negative, value for clockSkewInSec.
I also consider it a bug that setting the clock skew to 0 causes the default to be used, because the value is checked for truthiness, instead of compared against undefined and/or null. This is also a new change, here: 68238fb#diff-685e26c24f3c008856834f8b4a350d5472b6aea01a623c31a8513f6cc599c57fR2121
The text was updated successfully, but these errors were encountered: