Skip to content
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

System.system_time can drift due to time warp and cause tokens to be valid for longer then expected #41

Closed
Schultzer opened this issue May 1, 2024 · 12 comments

Comments

@Schultzer
Copy link
Contributor

After reading the Phoenix docs, I realized that System.system_time is used to sign and encrypt tokens, and using an unreliable timestamp is a security issue, something I've raised before in this thread regarding guardian: https://elixirforum.com/t/guardian-generating-an-expired-token-because-system-system-time-datetime-is-this-time-warp/56110

I recommend using DateTime.to_unix(DateTime.utc_now()) instead.

@josevalim
Copy link
Member

The operation you propose is equivalent to System.os_time and it also can drift, so I am not sure if it is any better. The benefit of system_time is that it amortizes the drift in case it happens?

@Schultzer
Copy link
Contributor Author

Schultzer commented May 1, 2024

Interesting, why are people experiencing the difference?

It makes sense to rely on the System.os_time instead since it would likely already be synchronized with NTP.

@josevalim
Copy link
Member

This comment in the discussion summarizes it well: https://elixirforum.com/t/guardian-generating-an-expired-token-because-system-system-time-datetime-is-this-time-warp/56110/28

I disagree with the description of System.system_time being unreliable but I agree that, in this case, we want to err on the side of the different machines agreeing on a time source sooner than later (i.e. use os_time, no amortization) . I don't see this being an actual issue in production machines, except dev machines going to sleep or on the scenarios described as "poor administration".

I will consult security folks anyway and do a new release if necessary. Thanks!

@Schultzer
Copy link
Contributor Author

Sounds good; there is also a minor doc issue:

Defaults to `System.system_time(:second)`
should be millisecond
defp now_ms, do: System.system_time(:millisecond)
.

Depending on the outcome above, I'll hold on pushing a PR.

@josevalim
Copy link
Member

Can you please send a PR for the docs anyway? And then we fix os_time in a separate PR. :) Thanks!

@josevalim
Copy link
Member

Yes, so it seems there is no issuehere. The drift can be arbitrarily big if the OS clocks lie to us but, if they lie to you, os_time will be wrong anyway. So the question is: in case the clock was wrong, would rather have large time jumps or correct over time?

I can't choose one answer here and, given the fact OTP 26 has better warp modes (with warnings) and the lack of evidence this is actually an issue, I will err on the side of no change for now. Glad to change my mind if there is a clear example of this being harmful over os_time. Thanks!

@josevalim josevalim closed this as not planned Won't fix, can't repro, duplicate, stale May 2, 2024
@Schultzer
Copy link
Contributor Author

Schultzer commented May 2, 2024

I'm afraid I have to disagree. As far as I know, then system_time is not synchronized with NTP, which os_time is very likely to be on all modern OSs. Changing the timezone is a moot point, in my opinion, since the timestamp is UTC.

To be clear, this is about using a synchronized clock, ideally NTP.

Furthermore, this also differs from how phx.gen.auth deals with timestamps.

@josevalim
Copy link
Member

As far as I know, then system_time is not synchronized with NTP, which os_time is very likely to be on all modern OSs.

system_time is synchronized with NTP unless you have large gaps on os_time, which has been my argument.

@josevalim
Copy link
Member

And can you please expand the phx.gen.auth bits?

@Schultzer
Copy link
Contributor Author

As far as I know, then system_time is not synchronized with NTP, which os_time is very likely to be on all modern OSs.

system_time is synchronized with NTP unless you have large gaps on os_time, which has been my argument.

Is it continuously synchronized, or could system_time diverge from the OS?

phx.gen.auth uses DateTime to timestamp session tokens.

@josevalim
Copy link
Member

Alright, being consistent is probably the most tangible benefit at this point, so I will go ahead with the changes.

josevalim added a commit that referenced this issue May 2, 2024
@josevalim
Copy link
Member

Done, 2.1.0 is out, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants