A session with no expiry or a 90-day timeout hands attackers an indefinitely valid credential from a single stolen cookie. NIST 800-63B §7.2 and PCI-DSS Req-8.2.8 both require session termination after a defined inactivity period — for good reason. A user who forgets to log out on a shared machine, or whose cookie is skimmed from an insecure connection, can have their account accessed for weeks or months with no recourse. OWASP A07 specifically lists insufficient session expiration as an authentication failure vector.
High because a non-expiring or excessively long-lived session token gives an attacker durable account access that persists long after the original compromise.
Set an explicit session lifetime rather than relying on a framework default that may be undocumented. For general SaaS, 7 days is a reasonable balance between security and UX; for finance or health apps, use 24 hours or less:
// NextAuth example in authOptions
session: {
strategy: 'jwt',
maxAge: 7 * 24 * 60 * 60, // 7 days
updateAge: 24 * 60 * 60, // extend on activity
}
Pair short session lifetimes with refresh token rotation so active users are not logged out while dormant sessions are expired.
ID: saas-authentication.session-management.session-expiry
Severity: high
What to look for: Check auth library configuration for session lifetime settings. In NextAuth: session.maxAge. In Supabase: JWT expiry and refresh token settings. In Clerk: session duration. In custom implementations: cookie maxAge or expires values. Also check if sessions are truly stateful (can be revoked) or purely JWT-based (cannot be revoked before expiry). Count all instances found and enumerate each.
Pass criteria: Session lifetime is configured and does not exceed 30 days for regular sessions. Inactivity timeouts are preferred over absolute expiry. The configured value is explicitly set — not relying on a framework's undocumented default.
Fail criteria: No session expiry configured (relying on browser session cookies only, or framework defaults that may be very long). Session lifetime is configured to more than 30 days without a corresponding short-lived access token and refresh token scheme.
Skip (N/A) when: No session-based authentication detected. Signal: API-key-only authentication, or no auth library present.
Detail on fail: "No session maxAge configured in NextAuth options — sessions may not expire" or "Session maxAge set to 7776000 (90 days) with no refresh token rotation — sessions live too long".
Remediation: Long-lived sessions are a significant risk: a stolen session cookie remains valid for the entire window. Set an appropriate timeout:
// NextAuth
export const authOptions = {
session: {
strategy: 'jwt',
maxAge: 7 * 24 * 60 * 60, // 7 days
}
}
For sensitive applications (finance, health), 24 hours or less is appropriate. For general SaaS, 7 days is a reasonable balance. Pair with refresh token rotation (see next check) for smooth UX without sacrificing security.