A critical security vulnerability was discovered where API keys from one user account would persist in localStorage after logout, allowing the next user logging in on the same device to access the previous user's API keys. This affected all AI provider API keys stored in the application.
- Incomplete Logout Process: The logout flow only signed out from Convex but didn't clear sensitive localStorage data
- Persistent Encryption Keys: The master encryption key used to encrypt API keys persisted after logout
- No User Context Validation: API keys were stored without user-specific namespacing
- High Severity: Complete access to previous user's AI provider API keys
- Affected Data: OpenAI, Anthropic, Google, and other provider API keys
- Attack Vector: Any subsequent user on the same device after logout
- Added comprehensive cleanup of all API keys (plain and encrypted)
- Clear master encryption key and fingerprint
- Remove all user preferences and legacy data
- Pattern-based cleanup for any app-prefixed keys
// Clear all API keys for each provider
for (const providerId of Object.keys(AI_PROVIDERS)) {
localStorage.removeItem(API_KEY_STORAGE_PREFIX + providerId);
localStorage.removeItem(API_KEY_STORAGE_PREFIX + providerId + '_encrypted');
localStorage.removeItem(API_KEY_STORAGE_PREFIX + providerId + '_encrypted_flag');
}
// Clear encryption keys
clearEncryptionKeys();
// Pattern-based cleanup
const keysToRemove = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && (key.startsWith('c3chat_') || key.startsWith('apiKey_'))) {
keysToRemove.push(key);
}
}- Track last logged-in user ID
- Detect when a different user logs in
- Automatically clear all sensitive data on user switch
- Force page reload for clean state
useEffect(() => {
if (loggedInUser && loggedInUser._id !== lastUserId) {
if (lastUserId !== null) {
// User switch detected - clear sensitive data
const keysToRemove = [];
// ... pattern matching for sensitive keys
keysToRemove.forEach(key => localStorage.removeItem(key));
window.location.reload();
}
setLastUserId(loggedInUser._id);
}
}, [loggedInUser, lastUserId]);- Added
clearEncryptionKeys()function - Removes master encryption key and fingerprint
- Clears all encrypted data flags
Created comprehensive tests in /src/__tests__/security-api-key-isolation.test.tsx:
- Verify complete cleanup on logout
- Test user switch detection
- Validate encryption key removal
- Check legacy format handling
- API Keys: All provider API keys (plain and encrypted)
- Encryption: Master key, fingerprint, encrypted flags
- Preferences: Provider and model selections
- Legacy Data: Any old format API keys
- Login as User A and add API keys
- Logout using the Sign Out button
- Login as User B
- Verify no API keys are present
- Check browser console for cleanup logs
- Consider server-side API key storage for enhanced security
- Implement user-specific key namespacing
- Add periodic key rotation
- Monitor for unauthorized API key access
- This fix requires no database changes
- Browser refresh forced on user switch for clean state
- Backwards compatible with existing encrypted keys
- No user action required - automatic cleanup
- Discovered: June 19, 2025
- Fixed: June 19, 2025
- Severity: Critical
- Type: Information Disclosure / Privilege Escalation
- CVSS Score: 8.8 (High)