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

385 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`
```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)
```blade
<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`
```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
### Option 1: Reduce Remember Me Duration ⭐ **RECOMMENDED**
**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:**
```php
// 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:**
```php
// 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:**
```php
'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):**
```markdown
## 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):**
```markdown
- **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:**
```php
// 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
- [x] Analyze session configuration
- [x] Identify remember me functionality
- [x] 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)
### 3. 🔍 Security Review **RECOMMENDED**
- [ ] 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)
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
### Recommended New Values
**File:** `config/timebank_cc.php`
```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)
```sql
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)
### Recommended Next Steps (Priority Order)
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