Major Security Improvements:

- Enhanced user fingerprinting with WebGL, Canvas, and Audio fingerprinting
- Hardware binding to prevent F5/Ctrl+F5 abuse
- Persistent storage across browser sessions (localStorage + sessionStorage)
- Global demo session counter with 10 session limit per device
- Multi-tab protection (max 2 tabs simultaneously)
- Anti-reset protection with hardware mismatch detection

Demo Session Protection:
- Advanced fingerprint generation with CPU benchmarking
- Enhanced validation with cryptographic verification
- Automatic cleanup and session completion tracking
- Cooldown periods between sessions (1min + 15min completion)
- Weekly partial reset of global counters

Fixes:
- Fixed SessionTimer console spam after connection disconnect
- Added missing registerEnhancedDemoSessionUsage method
- Corrected method calls from generateUserFingerprint to generateAdvancedUserFingerprint
- Implemented proper event handling for connection state changes

WebRTC Improvements:
- Added peer-disconnect, new-connection, and connection-cleaned events
- Enhanced connection cleanup with proper UI notifications
- Fixed SessionTimer state management during disconnections
- Prevented infinite re-rendering and console logging

Performance Optimizations:
- Auto-save persistent data every 30 seconds
- Periodic cleanup of old session data (every 6 hours)
- Memory management for used preimages (10k limit)
- Tab heartbeat system for multi-tab detection

Testing:
- Demo sessions now properly enforce limits
- P2P anonymity maintained (no server validation)
- Compatible with incognito mode restrictions
- Resistant to common abuse techniques
This commit is contained in:
lockbitchat
2025-08-16 20:58:42 -04:00
parent 32635839c6
commit e4273f5150
5 changed files with 697 additions and 136 deletions

View File

@@ -163,7 +163,7 @@ const EnhancedMinimalHeader = ({
React.createElement('p', {
key: 'subtitle',
className: 'text-xs sm:text-sm text-muted hidden sm:block'
}, 'End-to-end freedom. v4.0.02.88')
}, 'End-to-end freedom. v4.0.03.00')
])
]),

View File

@@ -2,12 +2,17 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
const [currentTime, setCurrentTime] = React.useState(timeLeft || 0);
const [showExpiredMessage, setShowExpiredMessage] = React.useState(false);
const [initialized, setInitialized] = React.useState(false);
const [connectionBroken, setConnectionBroken] = React.useState(false);
const [connectionBroken, setConnectionBroken] = React.useState(false);
const [loggedHidden, setLoggedHidden] = React.useState(false);
React.useEffect(() => {
if (connectionBroken) {
console.log('⏱️ SessionTimer initialization skipped - connection broken');
if (!loggedHidden) {
console.log('⏱️ SessionTimer initialization skipped - connection broken');
setLoggedHidden(true);
}
return;
}
@@ -23,17 +28,22 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
setCurrentTime(initialTime);
setInitialized(true);
}, [sessionManager, connectionBroken]);
setLoggedHidden(false);
}, [sessionManager, connectionBroken]);
React.useEffect(() => {
if (connectionBroken) {
console.log('⏱️ SessionTimer props update skipped - connection broken');
if (!loggedHidden) {
console.log('⏱️ SessionTimer props update skipped - connection broken');
setLoggedHidden(true);
}
return;
}
if (timeLeft && timeLeft > 0) {
setCurrentTime(timeLeft);
}
setLoggedHidden(false);
}, [timeLeft, connectionBroken]);
React.useEffect(() => {
@@ -42,7 +52,10 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
}
if (connectionBroken) {
console.log('⏱️ Timer interval skipped - connection broken');
if (!loggedHidden) {
console.log('⏱️ Timer interval skipped - connection broken');
setLoggedHidden(true);
}
return;
}
@@ -50,7 +63,6 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
return;
}
const interval = setInterval(() => {
if (connectionBroken) {
console.log('⏱️ Timer interval stopped - connection broken');
@@ -81,22 +93,18 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
}, 1000);
return () => {
clearInterval(interval);
};
}, [initialized, currentTime, sessionManager, connectionBroken]);
}, [initialized, currentTime, sessionManager, connectionBroken]);
React.useEffect(() => {
const handleSessionTimerUpdate = (event) => {
if (event.detail.timeLeft && event.detail.timeLeft > 0) {
setCurrentTime(event.detail.timeLeft);
}
};
const handleForceHeaderUpdate = (event) => {
if (sessionManager && sessionManager.hasActiveSession()) {
const newTime = sessionManager.getTimeLeft();
setCurrentTime(newTime);
@@ -105,28 +113,41 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
const handlePeerDisconnect = (event) => {
console.log('🔌 Peer disconnect detected in SessionTimer - stopping timer permanently');
setConnectionBroken(true);
setConnectionBroken(true);
setCurrentTime(0);
setShowExpiredMessage(false);
setLoggedHidden(false);
};
const handleNewConnection = (event) => {
console.log('🔌 New connection detected in SessionTimer - resetting connection state');
setConnectionBroken(false);
setConnectionBroken(false);
setLoggedHidden(false);
};
const handleConnectionCleaned = (event) => {
console.log('🧹 Connection cleaned - resetting SessionTimer state');
setConnectionBroken(false);
setCurrentTime(0);
setShowExpiredMessage(false);
setInitialized(false);
setLoggedHidden(false);
};
document.addEventListener('session-timer-update', handleSessionTimerUpdate);
document.addEventListener('force-header-update', handleForceHeaderUpdate);
document.addEventListener('peer-disconnect', handlePeerDisconnect);
document.addEventListener('new-connection', handleNewConnection);
document.addEventListener('connection-cleaned', handleConnectionCleaned);
return () => {
document.removeEventListener('session-timer-update', handleSessionTimerUpdate);
document.removeEventListener('force-header-update', handleForceHeaderUpdate);
document.removeEventListener('peer-disconnect', handlePeerDisconnect);
document.removeEventListener('new-connection', handleNewConnection);
document.removeEventListener('connection-cleaned', handleConnectionCleaned);
};
}, [sessionManager]);
}, [sessionManager]);
if (showExpiredMessage) {
return React.createElement('div', {
@@ -145,20 +166,33 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
}
if (!sessionManager) {
console.log('⏱️ SessionTimer hidden - no sessionManager');
if (!loggedHidden) {
console.log('⏱️ SessionTimer hidden - no sessionManager');
setLoggedHidden(true);
}
return null;
}
if (connectionBroken) {
console.log('⏱️ SessionTimer hidden - connection broken');
if (!loggedHidden) {
console.log('⏱️ SessionTimer hidden - connection broken');
setLoggedHidden(true);
}
return null;
}
if (!currentTime || currentTime <= 0) {
console.log('⏱️ SessionTimer hidden - no time left');
if (!loggedHidden) {
console.log('⏱️ SessionTimer hidden - no time left');
setLoggedHidden(true);
}
return null;
}
if (loggedHidden) {
setLoggedHidden(false);
}
const totalMinutes = Math.floor(currentTime / (60 * 1000));
const totalSeconds = Math.floor(currentTime / 1000);
@@ -179,8 +213,8 @@ const SessionTimer = ({ timeLeft, sessionType, sessionManager }) => {
};
const getTimerStyle = () => {
const totalDuration = sessionType === 'demo' ? 6 * 60 * 1000 : 60 * 60 * 1000;
const timeProgress = (totalDuration - currentTime) / totalDuration;
const totalDuration = sessionType === 'demo' ? 6 * 60 * 1000 : 60 * 60 * 1000;
const timeProgress = (totalDuration - currentTime) / totalDuration;
let backgroundColor, textColor, iconColor, iconClass, shouldPulse;
@@ -247,4 +281,4 @@ window.updateSessionTimer = (newTimeLeft, newSessionType) => {
}));
};
console.log('✅ SessionTimer loaded with fixes and improvements');
console.log('✅ SessionTimer loaded with anti-spam logging fixes');