fix(backend): store token expiry as UTC instead of server local time - #972
Open
omlahore wants to merge 1 commit into
Open
fix(backend): store token expiry as UTC instead of server local time#972omlahore wants to merge 1 commit into
omlahore wants to merge 1 commit into
Conversation
datetime.fromtimestamp(x / 1000) with no tz argument returns a naive datetime in the server's local time. With USE_TZ = True, Django stamps that naive value as UTC, so on a host whose local timezone is not UTC the stored expiry is shifted by the UTC offset. Where the offset is positive (Asia/Kolkata, +5:30) a token outlives the expiry the user asked for. Where it is negative (America/New_York, -5:00) it expires early. Pass tz=dt_timezone.utc at each site, matching what api/views/audit.py and backend/schema.py already do. Affected: graphene/mutations/service_accounts.py service account token expiry (x2) graphene/mutations/environment.py token expiry (x2) graphene/mutations/lockbox.py lockbox expiry ee/authentication/scim/graphene/queries.py SCIM log filtering (read path) The shipped docker-compose does not set TZ and Docker defaults to UTC, so a default deployment is unaffected. It needs a non-UTC host: a bare-metal install, a container run with TZ set, or a dev machine. This also silences "RuntimeWarning: DateTimeField received a naive datetime while time zone support is active" on these writes. Reported privately to security@phase.dev first; opening publicly at the maintainers' request.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported privately to
security@phase.devon 12 Aug and opening it here at the maintainers' request.The bug
datetime.fromtimestamp(x / 1000)with notzargument returns a naive datetime in the server's local time. WithUSE_TZ = True(settings.py:437), Django interprets that naive value as UTC on write, so on any host whose local timezone is not UTC the stored expiry is shifted by the UTC offset.Where the offset is positive, a token outlives the expiry the user asked for.
Reproduction
A user requests an expiry of
2026-01-01T00:00:00Z, sent as epoch ms1767225600000:UTC2026-01-01T00:00:00+00:002026-01-01T00:00:00+00:00Asia/Kolkata2026-01-01T05:30:00+00:002026-01-01T00:00:00+00:00America/New_York2025-12-31T19:00:00+00:002026-01-01T00:00:00+00:00Call sites
graphene/mutations/service_accounts.pygraphene/mutations/environment.pygraphene/mutations/lockbox.pyee/authentication/scim/graphene/queries.pyThe codebase already does this correctly in
api/views/audit.pyandbackend/schema.py, which is what made these stand out. This PR just makes the remaining sites match, including thetimezone as dt_timezonealias those files already use (needed inenvironment.py, which imports Django'stimezoneseparately).Scope
The shipped
docker-composedoes not setTZand Docker defaults to UTC, so a default self-hosted deployment and Phase Cloud are unaffected. It needs a host with a non-UTC local timezone: a bare-metal or non-Docker install, a container run withTZset, or a developer machine. Not remotely triggerable, and the drift is bounded by the UTC offset.This also silences
RuntimeWarning: DateTimeField received a naive datetime while time zone support is activeon these writes.Left alone
api/utils/syncing/github/actions.py:226has the same naive call, but it formats a GitHub rate-limit message for display rather than writing aDateTimeField. Happy to include it if you'd like consistency.