fix(auth): fail closed when a session's stored expiry is unparseable#1498
Open
nickmopen wants to merge 1 commit into
Open
fix(auth): fail closed when a session's stored expiry is unparseable#1498nickmopen wants to merge 1 commit into
nickmopen wants to merge 1 commit into
Conversation
authenticateSessionToken rejected revoked and past-dated sessions, but a session whose stored expires_at is malformed/empty parsed to NaN, and `NaN <= Date.now()` is false — so it authenticated as if it never expired. Guard the parse with Number.isFinite so an unparseable expiry fails closed (rejected), matching the expired-session path. Mirrors the existing expired-session test with a malformed-expiry case. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1498 +/- ##
=======================================
Coverage 95.44% 95.44%
=======================================
Files 194 194
Lines 21096 21097 +1
Branches 7630 7630
=======================================
+ Hits 20136 20137 +1
Misses 383 383
Partials 577 577
🚀 New features to boost your workflow:
|
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.
Summary
authenticateSessionToken(src/auth/security.ts) gates a session on:A session whose stored
expires_atis malformed or empty parses toNaN, andNaN <= Date.now()isfalse. Combined with a nullrevokedAt, the session is then treated as valid and never-expiring — a fail-open on the expiry check.Problem
expires_atis normally written by our own session-creation path, but the auth check should not depend on that invariant holding for every row (DB drift, a partial write, a manually inserted row). An unparseable expiry must be rejected, not silently honored forever. This matches the project's fail-closed posture (e.g. #1368 "fail closed when … unreadable").Fix
Parse once and guard with
Number.isFinite, so an unparseable expiry fails closed exactly like an expired one. Revoked and past-dated behavior is unchanged.Validation
Run from repo root (Node 24):
npm run test:ci # GATE_EXIT=0 — 4607 passed / 4 skipped; typecheck, coverage, workers, MCP, UI all greenAdded a regression assertion alongside the existing expired-session test in
test/unit/auth.test.ts: a session withexpires_at = "not-a-date"now authenticates tonull(it would have returned a valid identity before this fix).