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
cookielib uses time.time(), making incorrect checks of expiration times in cookies #66492
Comments
The cookielib module uses time.time(), which produces a timestamp in the local timezone (as read from the system time?), as the timestamp against which expiration dates in cookies are compared. However, typical usage of HTTP cookies would be specifying the expiration date in UTC. This assumption seems to be supported for example by the inclusion of cookielib.http2time, which (only) supports UTC timestamps. This behaviour is also included in e.g. MozillaCookieJar, which (erroneously) excludes cookies from being saved/loaded based on the local timestamp from time.time(). See the attached file for a small example where the check if a cookie is expired against a UTC time is correct but the check against local time fails (simulating the behaviour of the cookielib module). |
If you have not, please check if this issue applies to 3.4, and post a 3.4 version of the test file. In the absence of a standard, I am not sure if this is a bug, and even if we call it such, whether 2.7 should be changed. |
I've checked and an updated test file for 3.4 shows the same behaviour in the renamed module http.cookiejar. Even though no standard exists I hope 3.4+ would be changed to simplify the cookie handling, since there is a lot of hassle converting UTC times to local times (which in general should be avoided to avoid introducing further problems with e.g. daylight savings). |
time.time() returns the current time in seconds since Epoch You can get local time using datetime.fromtimestamp(ts). I don't know whether there is an issue with cookie.is_expired() but it from datetime import datetime, timezone
now = datetime.now(timezone.utc) # the current time
seconds_since_epoch = now.timestamp()
seconds_since_epoch = time.time() # might be less precise |
Note the .timestamp() method will work correctly if the datetime object is expressed in *local time*, which is not what Rebecka's code uses. Otherwise the incantation is a bit more complex: https://docs.python.org/3/library/datetime.html#datetime.datetime.timestamp (also .timestamp() doesn't exist in 2.7, in which case the manual computation must also be used) |
timestamp() method works correctly for an aware datetime objects The issue is not that it is a manual computation, #XXX WRONG, DO NOT DO IT On older Python versions, given a utc time as a naive datetime ts = (utc_dt - datetime(1970, 1, 1)).total_seconds()
utc_dt = datetime(1970, 1, 1) + timedelta(seconds=ts) # in reverse |
The last example assumes that time.gmtime(0) is 1970-01-01 00:00:00Z |
Akira is correct: using time.mktime to produce the expiration date for the cookie is wrong (thank you very much for the pointers!). Using e.g. http.cookiejar.http2time with a HTTP formatted date string gives a correct time stamp (with which cookie.is_expired succeeds), so this was not a bug (just user error...). |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: