Files
igny8/AUTHENTICATION-AUDIT-REPORT.md
IGNY8 VPS (Salman) 4fb3a144d7 messy logout fixing
2025-12-15 12:01:41 +00:00

12 KiB

🔍 Authentication System Audit Report

Random User Logout Issues - Complete Analysis

Date: December 15, 2025
Status: ⚠️ CRITICAL ISSUES FOUND
Priority: HIGH


📋 Executive Summary

This audit identified 8 CRITICAL issues and 5 moderate issues that could cause random user logouts. The system has multiple aggressive logout triggers that were likely implemented to prevent session contamination, but these are now causing false positives and logging out legitimate users.


🔴 CRITICAL ISSUES (Immediate Action Required)

1. Aggressive Session Integrity Checks in Middleware

Location: backend/igny8_core/auth/middleware.py (Lines 55-82)

Problem: The AccountContextMiddleware validates _account_id and _user_id stored in session on EVERY request. If there's ANY mismatch, it immediately logs out the user.

# Session contamination detected - force logout
if stored_account_id and stored_account_id != request.account.id:
    logout(request)
    return JsonResponse({'error': 'Session integrity violation...'})

Why This Causes Random Logouts:

  • Race conditions during account switching
  • Database updates to account relationships
  • Session data not yet synchronized
  • Multiple tabs/windows with different accounts
  • Session persistence delays

Impact: HIGH - Affects all authenticated users on every request


2. JWT Token Expiry Too Short

Location: backend/igny8_core/settings.py (Line 523)

Problem:

JWT_ACCESS_TOKEN_EXPIRY = timedelta(minutes=15)  # Too short!

Why This Causes Random Logouts:

  • Users idle for >15 minutes get logged out
  • Token refresh mechanism has race conditions
  • Frontend proactive refresh (12 minutes) doesn't always succeed
  • Network delays can cause refresh to happen after expiry

Impact: HIGH - Affects users during long operations or idle periods


Location: backend/igny8_core/settings.py (Lines 100-101)

Problem:

SESSION_COOKIE_AGE = 86400  # 24 hours
SESSION_SAVE_EVERY_REQUEST = False  # Session not extended on activity

Why This Causes Random Logouts:

  • Session expires exactly 24 hours after login, even if user is active
  • User working for >24 hours gets logged out mid-session
  • No sliding window - fixed expiry time

Impact: MODERATE - Affects users with long sessions


4. Account/Plan Validation on Every Request

Location: backend/igny8_core/auth/middleware.py (Lines 181-195)

Problem: Middleware calls validate_account_and_plan() on EVERY request, and if validation fails (account status changes, plan becomes inactive), user is IMMEDIATELY logged out.

validation_error = self._validate_account_and_plan(request, request.user)
if validation_error:
    logout(request)  # Immediate logout
    return JsonResponse({...})

Why This Causes Random Logouts:

  • Account status changes during active session (admin updates)
  • Plan expiry/renewal processing
  • Database replication lag
  • Race conditions during billing operations

Impact: HIGH - Affects users when account/plan changes


5. Multiple Frontend Logout Triggers

Location: frontend/src/services/api.ts (Lines 194-200, 321-322, 327-328)

Problem: Frontend has multiple aggressive logout triggers:

// On 403 error:
if (errorMessage?.includes?.('Authentication credentials')) {
    logout();
    window.location.href = '/signin';
}

// On refresh token failure:
logout();

Why This Causes Random Logouts:

  • 403 errors are triggered for permission issues (NOT just auth)
  • Network timeouts interpreted as auth failures
  • Plan/limit errors (402) causing logouts
  • Race conditions during token refresh

Impact: HIGH - False positive logouts on permission/network errors


6. Proactive Token Refresh Race Condition

Location: frontend/src/layout/AppLayout.tsx (Lines 153-167)

Problem: Frontend proactively refreshes token every 12 minutes, but this can race with API calls:

const tokenRefreshInterval = setInterval(async () => {
    await authState.refreshToken();
}, 720000); // 12 minutes

Why This Causes Random Logouts:

  • Refresh fails → logout triggered
  • Old token used during refresh window
  • Multiple tabs triggering simultaneous refreshes
  • Network delays causing refresh to fail

Impact: MODERATE - Periodic logout risk


7. Frontend Auto-Refresh User Data Every 2 Minutes

Location: frontend/src/layout/AppLayout.tsx (Lines 169, 91-180)

Problem: Frontend calls refreshUser() every 2 minutes, on tab focus, and on visibility change. If ANY of these fail, it could trigger logout.

const intervalId = setInterval(() => refreshUserData(), 120000);

Why This Causes Random Logouts:

  • API errors during refresh
  • Network issues
  • Backend temporary unavailability
  • Race conditions with other API calls

Impact: MODERATE - Periodic logout risk


8. CSRF Token Issues (SameSite=Strict)

Location: backend/igny8_core/settings.py (Line 99)

Problem:

SESSION_COOKIE_SAMESITE = 'Strict'  # Too restrictive

Why This Causes Random Logouts:

  • Cookies not sent on cross-site navigation
  • External redirects (OAuth, payment gateways) lose session
  • Browser compatibility issues
  • Subdomain navigation issues

Impact: MODERATE - Affects users with specific navigation patterns


⚠️ MODERATE ISSUES

9. No Session Backend Configuration

Location: backend/igny8_core/settings.py

Problem: No explicit session backend configured, defaults to database sessions.

Risk: Database connection issues → session loss → logout


10. JWT Refresh Token = 30 Days but No Rotation

Location: backend/igny8_core/settings.py (Line 524)

Problem: Long-lived refresh tokens without rotation increase security risk.

Risk: Stolen refresh token valid for 30 days


11. Multiple Authentication Methods Without Coordination

Location: backend/igny8_core/settings.py (Lines 251-254)

Problem: Three auth methods (API Key, JWT, Session) don't coordinate state.

Risk: Confusion about which method is authoritative, inconsistent logout behavior


Location: frontend/src/store/authStore.ts (Lines 147-158)

Problem: Logout clears ALL cookies including domain variants.

Risk: Unintended side effects, potential conflicts with other services


13. No Graceful Degradation for Network Errors

Location: frontend/src/services/api.ts

Problem: Network timeouts treated same as auth errors.

Risk: Temporary network issues cause logout


🔧 ROOT CAUSE ANALYSIS

Primary Causes:

  1. Over-aggressive session validation - False positives
  2. Short token expiry + unreliable refresh - Race conditions
  3. Multiple logout triggers - No coordination
  4. No distinction between auth errors and other errors - False positive logouts

Secondary Causes:

  1. Fixed session expiry (no sliding window)
  2. SameSite=Strict blocking legitimate use cases
  3. Frequent auto-refresh increasing failure surface

IMMEDIATE (Do First):

  1. Remove session integrity checks from middleware

    • Lines 55-82 in backend/igny8_core/auth/middleware.py
    • Only validate on sensitive operations, not every request
  2. Increase JWT token expiry

    • Change from 15 minutes to 60 minutes
    • JWT_ACCESS_TOKEN_EXPIRY = timedelta(hours=1)
  3. Enable session sliding window

    • SESSION_SAVE_EVERY_REQUEST = True
    • Or increase to 7 days: SESSION_COOKIE_AGE = 604800
  4. Fix frontend 403 error handling

    • Don't logout on permission errors
    • Only logout on explicit "not authenticated" errors
    • Check error message more carefully
  5. Add retry logic for token refresh

    • Retry 2-3 times before giving up
    • Add exponential backoff

SHORT TERM (Next Sprint):

  1. Change SameSite to Lax

    • SESSION_COOKIE_SAMESITE = 'Lax'
  2. Reduce auto-refresh frequency

    • Change from 2 minutes to 5-10 minutes
    • Remove refresh on focus/visibility (keep only on mount)
  3. Add error classification

    • Distinguish network errors, permission errors, auth errors
    • Only logout on auth errors
  4. Add request deduplication

    • Prevent multiple simultaneous token refreshes

LONG TERM (Future):

  1. Implement JWT token rotation
  2. Add session heartbeat endpoint
  3. Implement connection quality monitoring
  4. Add user session dashboard

🧪 TESTING RECOMMENDATIONS

  1. Test session expiry scenarios

    • Leave user idle for 15, 30, 60, 90 minutes
    • Verify no unexpected logout
  2. Test account changes during active session

    • Admin updates account status
    • Plan renewal/expiry
    • Verify user not logged out
  3. Test network failure scenarios

    • Simulate network timeout
    • Disconnect/reconnect
    • Verify graceful recovery, no logout
  4. Test multi-tab behavior

    • Open multiple tabs
    • Perform actions in parallel
    • Verify no conflicts
  5. Test token refresh under load

    • Simulate concurrent API calls during refresh
    • Verify no race conditions

📊 IMPACT ASSESSMENT

Issue Severity Frequency User Impact Fix Complexity
Session integrity checks HIGH Every request Very High Low
JWT expiry too short HIGH Every 15min High Low
Account validation logout HIGH On changes Medium Medium
Frontend 403 logout HIGH On errors High Low
Token refresh race MEDIUM Every 12min Medium Medium
User auto-refresh MEDIUM Every 2min Low Low
SameSite Strict MEDIUM Specific flows Medium Low
Session expiry (24h) LOW After 24h Low Low

🎯 SUCCESS CRITERIA

After implementing fixes:

  • Users can work uninterrupted for 8+ hours
  • Account/plan changes don't force logout
  • Network errors don't cause logout
  • Token refresh succeeds >99.9% of time
  • Multi-tab usage works without issues
  • Zero false-positive "session contamination" logouts

📝 CONCLUSION

The random logout issue is caused by multiple over-aggressive authentication checks that were likely added to prevent session contamination. While the intent was good, the implementation creates too many false positives.

The fix requires:

  1. Removing session integrity checks from hot path
  2. Increasing token expiry and adding retry logic
  3. Better error classification
  4. Enabling session sliding window

Estimated effort: 2-3 days for all critical fixes
Risk level: Low (mostly configuration changes)
Testing required: Moderate (need to verify all auth flows)


Backend:

  • backend/igny8_core/auth/middleware.py (Lines 1-207)
  • backend/igny8_core/auth/utils.py (Lines 1-216)
  • backend/igny8_core/auth/backends.py (Lines 1-36)
  • backend/igny8_core/settings.py (Lines 93-108, 523-524)
  • backend/igny8_core/api/authentication.py (Lines 1-172)
  • backend/igny8_core/api/permissions.py (Lines 1-208)

Frontend:

  • frontend/src/store/authStore.ts (Lines 1-450)
  • frontend/src/services/api.ts (Lines 1-2561)
  • frontend/src/layout/AppLayout.tsx (Lines 1-300)

Report prepared by: GitHub Copilot
Audit methodology: Code review, flow analysis, error pattern analysis
Review status: Awaiting stakeholder review