Files
Oxicloud/migrations/20260507000000_session_family.sql
T
Edouard Vanbelle b90fa6f619 security: prevent re-use of refresh token (reduce surface for any stolen token)
Security: session hardening

  Refresh token rotation with theft detection (family_id)
  - Added family_id column to auth.sessions (migration 20260507000000_session_family.sql) grouping all tokens issued from the same login into a family
  - On refresh, the new session inherits the parent's family_id
  - If a revoked token is replayed (indicates the token was stolen after rotation), the entire family is immediately invalidated and a warning is logged — forcing re-authentication on all devices

  SameSite=Strict on refresh cookie
  - Access cookie stays SameSite=Lax (needed for top-level navigation)
  - Refresh cookie upgraded to SameSite=Strict — it is only ever used for explicit POST to /api/auth/refresh, never via cross-site navigation

  Refresh token TTL: 30 days → 7 days
  - With rotation, active sessions auto-renew and effectively never expire
  - Inactive sessions expire after 7 days instead of 30, reducing the theft window
2026-05-07 13:57:10 +02:00

20 lines
630 B
SQL

-- Add token family tracking to sessions.
--
-- family_id groups all refresh tokens issued from the same original login.
-- When a rotation detects a revoked token being replayed (possible theft),
-- the entire family is invalidated — forcing re-authentication on all devices
-- that shared that login event.
--
-- Existing sessions are seeded with family_id = id (each is its own family).
ALTER TABLE auth.sessions
ADD COLUMN family_id UUID;
UPDATE auth.sessions
SET family_id = id;
ALTER TABLE auth.sessions
ALTER COLUMN family_id SET NOT NULL;
CREATE INDEX idx_sessions_family_id ON auth.sessions(family_id);