[Bug 4004] New: `authorized_keys` `expiry-time=` keys keep authenticating one hour past expiry under DST
bugzilla-daemon at mindrot.org
bugzilla-daemon at mindrot.org
Sat Sep 12 08:31:34 AEST 2026
https://bugzilla.mindrot.org/show_bug.cgi?id=4004
Bug ID: 4004
Summary: `authorized_keys` `expiry-time=` keys keep
authenticating one hour past expiry under DST
Product: Portable OpenSSH
Version: 10.5p1
Hardware: Other
OS: Other
Status: NEW
Severity: critical
Priority: P5
Component: sshd
Assignee: unassigned-bugs at mindrot.org
Reporter: khush2792001 at gmail.com
Expected behavior
An `authorized_keys` entry with `expiry-time="YYYYMMDDHHMMSS"` stops
authenticating once that moment has passed. A key whose expiry was 30
minutes
ago must be refused.
## Actual behavior
When the expiry timestamp falls inside the local timezone's DST period,
the key
keeps authenticating for **one hour past the configured expiry**. A key
that
expired 30 minutes ago still logs in successfully.
Same binary, same procedure, same "expired 30 minutes ago" input; only
`TZ`
varies (run 2026-08-25, northern-hemisphere summer):
Root cause
`auth-options.c` parses the option with the same helper as certificate
validity:
```c
} else if (opt_match(&opts, "expiry-time")) {
...
if (parse_absolute_time(opt, &valid_before) != 0 ||
valid_before == 0) {
```
and `misc.c :: parse_absolute_time()` does `memset(&tm, 0, sizeof(tm))`
—
setting `tm_isdst = 0`, i.e. "DST not in effect" — then calls
`mktime()` without
ever setting `tm.tm_isdst = -1`. Every local timestamp is therefore
interpreted
as standard time, so a DST-period expiry resolves one hour late.
## Suggested fix
Identical to BUG-001 — one line in the non-UTC branch of
`parse_absolute_time()`:
```diff
+ tm.tm_isdst = -1; /* let mktime() consult tzdata
for this date */
tm.tm_wday = -1;
if ((tt = mktime(&tm)) == -1 && tm.tm_wday == -1)
```
Impact
- Any deployment expiring access via `expiry-time=` grants an extra
hour beyond
the stated deadline, for roughly half the year on DST-observing
hosts.
- **Fails open**: the error direction always favours continued access.
- **Silent**: no warning, and `sshd -T` does not surface per-key
options, so
operators have nothing to compare against their intent.
- Automated offboarding that sets `expiry-time` to "now" leaves a
one-hour
window in which the revoked key still works.
## Workaround
Run `sshd` with `TZ=UTC`, or remove the key outright rather than
relying on
`expiry-time` for time-critical revocation.
--
You are receiving this mail because:
You are watching the assignee of the bug.
More information about the openssh-bugs
mailing list