#!/usr/bin/env python """ Test script to detect and reproduce session contamination bugs Usage: docker exec igny8_backend python test_session_contamination.py """ import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'igny8_core.settings') django.setup() from django.contrib.sessions.models import Session from django.contrib.auth import get_user_model from django.test import RequestFactory from django.contrib.sessions.middleware import SessionMiddleware from igny8_core.auth.middleware import AccountContextMiddleware from datetime import datetime, timedelta User = get_user_model() def test_session_isolation(): """Test that sessions are properly isolated between users""" print("\n=== SESSION CONTAMINATION TEST ===\n") # Get test users try: developer = User.objects.get(username='developer') scale_user = User.objects.filter(account__slug='scale-account').first() if not scale_user: print("⚠️ No scale account user found, creating one...") from igny8_core.auth.models import Account scale_account = Account.objects.filter(slug='scale-account').first() if scale_account: scale_user = User.objects.create_user( username='scale_test', email='scale@test.com', password='testpass123', account=scale_account, role='owner' ) else: print("❌ No scale account found") return False print(f"✓ Developer user: {developer.username} (account: {developer.account.slug})") print(f"✓ Scale user: {scale_user.username} (account: {scale_user.account.slug if scale_user.account else 'None'})") except Exception as e: print(f"❌ Failed to get test users: {e}") return False # Check active sessions active_sessions = Session.objects.filter(expire_date__gte=datetime.now()) print(f"\n📊 Total active sessions: {active_sessions.count()}") # Count sessions by user user_sessions = {} for session in active_sessions: try: data = session.get_decoded() user_id = data.get('_auth_user_id') if user_id: user = User.objects.get(id=user_id) key = f"{user.username} ({user.account.slug if user.account else 'no-account'})" user_sessions[key] = user_sessions.get(key, 0) + 1 except: pass print("\n📈 Sessions by user:") for user_key, count in sorted(user_sessions.items(), key=lambda x: x[1], reverse=True): print(f" {user_key}: {count} sessions") # Check for session contamination patterns contamination_found = False # Pattern 1: Too many sessions for one user for user_key, count in user_sessions.items(): if count > 20: print(f"\n⚠️ WARNING: {user_key} has {count} sessions (possible proliferation)") contamination_found = True # Pattern 2: Check session cookie settings from django.conf import settings print(f"\n🔧 Session Configuration:") print(f" SESSION_COOKIE_NAME: {settings.SESSION_COOKIE_NAME}") print(f" SESSION_COOKIE_DOMAIN: {getattr(settings, 'SESSION_COOKIE_DOMAIN', 'Not set (good)')}") print(f" SESSION_COOKIE_SAMESITE: {getattr(settings, 'SESSION_COOKIE_SAMESITE', 'Not set')}") print(f" SESSION_COOKIE_HTTPONLY: {settings.SESSION_COOKIE_HTTPONLY}") print(f" SESSION_ENGINE: {settings.SESSION_ENGINE}") if getattr(settings, 'SESSION_COOKIE_SAMESITE', None) != 'Strict': print(f"\n⚠️ WARNING: SESSION_COOKIE_SAMESITE should be 'Strict' (currently: {getattr(settings, 'SESSION_COOKIE_SAMESITE', 'Not set')})") contamination_found = True # Test middleware isolation print(f"\n🧪 Testing Middleware Isolation...") factory = RequestFactory() # Simulate two requests from different users request1 = factory.get('/api/v1/test/') request1.user = developer request1.session = {} request2 = factory.get('/api/v1/test/') request2.user = scale_user request2.session = {} middleware = AccountContextMiddleware(lambda x: None) # Process requests middleware.process_request(request1) middleware.process_request(request2) # Check isolation account1 = getattr(request1, 'account', None) account2 = getattr(request2, 'account', None) print(f" Request 1 account: {account1.slug if account1 else 'None'}") print(f" Request 2 account: {account2.slug if account2 else 'None'}") if account1 and account2 and account1.id == account2.id: print(f"\n❌ CONTAMINATION DETECTED: Both requests have same account!") contamination_found = True else: print(f"\n✓ Middleware isolation working correctly") # Final result if contamination_found: print(f"\n❌ SESSION CONTAMINATION DETECTED") print(f"\nRecommended fixes:") print(f"1. Set SESSION_COOKIE_SAMESITE='Strict' in settings.py") print(f"2. Clear all existing sessions: Session.objects.all().delete()") print(f"3. Ensure users logout and re-login with fresh cookies") return False else: print(f"\n✅ No contamination detected - sessions appear isolated") return True if __name__ == '__main__': result = test_session_isolation() exit(0 if result else 1)