Files
timebank-cc-public/SESSION_EXPIRATION_ANALYSIS_2026-01-12.md
Ronald Huynen 2547717edb Initial commit
2026-03-23 21:37:59 +01:00

11 KiB
Raw Permalink Blame History

Session Expiration Analysis

Date: 2026-01-12 Issue: Session did not expire after over 1 day (user 161, organization 1) Status: ⚠️ WORKING AS DESIGNED (but needs review)


Issue Summary

User reported remaining logged in for over 1 day without session expiration. After investigation, this is working as intended due to the "Remember Me" functionality.


Root Cause Analysis

1. Session Configuration

File: config/session.php

'lifetime' => env('SESSION_LIFETIME', 480),  // Default: 480 minutes (8 hours)
'expire_on_close' => false,

Environment: .env

SESSION_LIFETIME=120  // 2 hours

Expected Behavior: Sessions should expire after 120 minutes (2 hours) of inactivity.

2. Remember Me Functionality

File: resources/views/auth/login.blade.php (line ~X)

<label for="remember_me" class="flex items-center">
    <x-jetstream.checkbox id="remember_me" name="remember" />
    {{ __('Remember me for :period', ['period' => daysToHumanReadable(timebank_config('auth.remember_me_days', 90))]) }}

Configuration: config/timebank_cc.php and config/timebank-default.php

'remember_me_days' => 90, // Number of days the "Remember me" checkbox will keep users logged in

Duration: 90 days = 129,600 minutes (60 × 24 × 90)

3. How Remember Me Works

When a user checks "Remember me" during login:

  1. Laravel creates a remember_token in the user's database record
  2. A cookie is set with this token lasting 90 days
  3. Even if the session expires (after 2 hours), the remember token keeps the user logged in
  4. The user remains authenticated for the full 90-day period

This is standard Laravel behavior and is working as designed.


Current Configuration Summary

Setting Value Duration Purpose
SESSION_LIFETIME 120 2 hours Session expires after 2 hours of inactivity
remember_me_days 90 90 days Remember Me cookie duration
password_timeout 10800 3 hours Password confirmation timeout
expire_on_close false - Session persists after browser close

Security Implications

Current Security Measures

  1. Session Encryption: SESSION_ENCRYPT=true
  2. HTTP Only Cookies: http_only => true (prevents JavaScript access)
  3. Secure Cookies: secure => env('SESSION_SECURE_COOKIE') (HTTPS only)
  4. Same-Site Policy: same_site => 'lax' (CSRF protection)
  5. Database Sessions: Stored in database, not filesystem
  6. IP Tracking: Last login IP stored for security monitoring

⚠️ Potential Security Concerns

  1. Long Remember Duration (90 days)

    • If a device is lost/stolen, attacker has 90-day access
    • User may forget they're logged in on shared computers
    • No mechanism to revoke all remember tokens globally
  2. No Idle Timeout for Remember Me

    • Regular sessions expire after 2 hours of inactivity
    • Remember Me bypasses this completely
    • User could be inactive for 89 days and still be logged in on day 90
  3. Profile Switching Session Variables

    • When switching to organization profile, session variables stored:
      • activeProfileType
      • activeProfileId
      • active_guard
    • These persist for the remember token duration (90 days)
    • No separate timeout for elevated guard sessions
  4. Shared Computer Risk

    • User logs in on public computer with "Remember Me" checked
    • Forgets to log out
    • Next person has 90-day access to that account

Privacy Policy Implications

The current privacy policy states:

File: references/gdpr/timebank_cc/2026-01-01/privacy-policy-FULL-en.md

Section 9. Security

  • "2-hour session timeouts"

Issue: This is misleading because:

  • Sessions timeout after 2 hours of inactivity (correct)
  • BUT Remember Me keeps users logged in for 90 days (not mentioned)
  • Users may think they're protected by 2-hour timeout when they're not

Recommendations

Change remember_me_days from 90 to 14 or 30 days

Pros:

  • Still convenient for users
  • Significantly reduces risk window
  • Industry standard (many sites use 14-30 days)

Implementation:

// config/timebank_cc.php
'remember_me_days' => 14, // Reduced from 90 to 14 days

Option 2: Add Idle Timeout for Remember Me

Implement additional check for last activity

Pros:

  • Remember Me users still logout after extended inactivity
  • Combines convenience with security

Implementation:

  • Add middleware to check last activity timestamp
  • If last activity > X days ago (e.g., 7 days), force re-authentication
  • Update remember token on each login to track last activity

Example Middleware Logic:

// Check if user hasn't been active in 7 days
if (Auth::user()->last_activity_at < now()->subDays(7)) {
    Auth::logout();
    return redirect()->route('login')->with('message', 'Session expired due to inactivity');
}

Option 3: Separate Session Lifetime for Elevated Guards

Different timeouts for regular vs elevated sessions

Configuration:

'auth' => [
    'remember_me_days' => 14, // Regular user sessions
    'elevated_session_lifetime' => 60, // 1 hour for bank/admin/org profiles
],

Pros:

  • Organizations/Banks/Admins have shorter session lifetime
  • Regular users maintain convenience
  • Better security for privileged accounts

Option 4: Update Privacy Policy REQUIRED

Add disclosure about Remember Me functionality

Add to Section 9 (Security):

## Session Security
- Regular sessions expire after 2 hours of inactivity
- "Remember Me" feature (optional) keeps you logged in for 90 days
  - Use only on trusted personal devices
  - Always log out on shared or public computers
  - You can revoke access by logging out from your account settings

Add to Section 3.4 (Technical Data):

- **Authentication tokens** (for "Remember Me" feature)
  - Optional remember me token (stored for 90 days if enabled)
  - Automatically deleted when you log out or token expires

Option 5: Add "Trusted Device" Management

Allow users to view and revoke remember tokens

Features:

  • Show list of devices where user is "remembered"
  • Display: Device type, IP address, last activity, location
  • "Revoke access" button to delete remember token
  • "Log out all devices" option

Implementation:

// User can revoke specific device
User::find($userId)->remember_tokens()->where('id', $tokenId)->delete();

// User can revoke all devices
User::find($userId)->remember_tokens()->delete();

Comparison with Industry Standards

Service Remember Me Duration Session Timeout
Timebank.cc (current) 90 days 2 hours
GitHub 30 days 2 weeks (idle)
Google "Forever" (until revoked) Variable
Facebook 90 days 30 days (idle)
Banking sites Not offered 5-15 minutes
AWS Console 12 hours 12 hours

Analysis: 90 days is on the longer side but not unprecedented. However, for a financial platform (time banking involves transactions), this may be too long.


Immediate Actions Required

1. Document Current Behavior

  • Analyze session configuration
  • Identify remember me functionality
  • Document security implications

2. ⚠️ Update Privacy Policy URGENT

  • Add Remember Me disclosure to Section 9 (Security)
  • Add authentication tokens to Section 3.4 (Technical Data)
  • Update all language versions (EN, NL, DE, FR, ES)
  • Assess if 90 days is appropriate for timebank platform
  • Consider reducing to 14-30 days
  • Evaluate implementing idle timeout for remember me
  • Consider separate timeouts for elevated guards (org/bank/admin)

4. 🛠️ Feature Enhancements OPTIONAL

  • Add "Trusted Devices" management page
  • Show active sessions with revoke capability
  • Add "Log out all devices" option
  • Display warning on login page about Remember Me duration

Testing Checklist

To verify session behavior:

Test 1: Regular Session (No Remember Me)

# 1. Log in without checking "Remember Me"
# 2. Wait 2 hours (or set SESSION_LIFETIME=1 for testing)
# 3. Refresh page
# Expected: User is logged out

Test 2: Remember Me Session

# 1. Log in WITH "Remember Me" checked
# 2. Close browser completely
# 3. Reopen browser and visit site
# Expected: User still logged in
# 4. Check database for remember_token in users table

Test 3: Profile Switch Persistence

# 1. Log in as user 161 with Remember Me
# 2. Switch to organization profile 1
# 3. Close browser
# 4. Reopen browser
# Expected: Still logged in as organization 1

Test 4: Token Expiration

# 1. Log in with Remember Me
# 2. Wait 90 days (or modify remember_me_days for testing)
# 3. Try to access site
# Expected: User is logged out, prompted to login

Proposed Configuration Changes

File: config/timebank_cc.php

'auth' => [
    // Reduced from 90 to 14 days for better security
    'remember_me_days' => 14,

    // NEW: Maximum idle time for remember me (7 days)
    'remember_me_max_idle_days' => 7,

    // NEW: Separate timeout for elevated guards (1 hour)
    'elevated_guard_timeout' => 60,
],

File: .env

# Regular session timeout (unchanged)
SESSION_LIFETIME=120

# NEW: Force re-authentication for sensitive operations
PASSWORD_CONFIRMATION_TIMEOUT=900

Database Schema for Trusted Devices (Optional Enhancement)

CREATE TABLE trusted_devices (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT UNSIGNED NOT NULL,
    device_name VARCHAR(255),
    ip_address VARCHAR(45),
    user_agent TEXT,
    remember_token VARCHAR(100) NOT NULL,
    last_activity_at TIMESTAMP NULL,
    expires_at TIMESTAMP NULL,
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,

    INDEX idx_user_id (user_id),
    INDEX idx_remember_token (remember_token),
    INDEX idx_expires_at (expires_at),

    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

Conclusion

The session not expiring is WORKING AS DESIGNED due to the Remember Me functionality. However, this behavior:

  1. ⚠️ Not clearly communicated to users in privacy policy
  2. ⚠️ May be too permissive for a financial platform (90 days is long)
  3. ⚠️ Lacks advanced controls (no device management, no idle timeout)
  1. HIGH PRIORITY: Update privacy policy to disclose Remember Me behavior
  2. MEDIUM PRIORITY: Reduce remember_me_days from 90 to 14-30 days
  3. MEDIUM PRIORITY: Implement idle timeout for remember me sessions
  4. LOW PRIORITY: Add trusted device management page
  5. LOW PRIORITY: Separate session lifetimes for elevated guards

Report Generated: 2026-01-12 Issue Status: Working as designed (requires policy update) Security Risk: Medium (long remember me duration) Action Required: Update privacy policy + consider reducing remember me duration