fix(#198): Strengthen WebSocket authentication
Implemented comprehensive authentication for WebSocket connections to prevent unauthorized access: Security Improvements: - Token validation: All connections require valid authentication tokens - Session verification: Tokens verified against BetterAuth session store - Workspace authorization: Users can only join workspaces they have access to - Connection timeout: 5-second timeout prevents resource exhaustion - Multiple token sources: Supports auth.token, query.token, and Authorization header Implementation: - Enhanced WebSocketGateway.handleConnection() with authentication flow - Added extractTokenFromHandshake() for flexible token extraction - Integrated AuthService for session validation - Added PrismaService for workspace membership verification - Proper error handling and client disconnection on auth failures Testing: - TDD approach: wrote tests first (RED phase) - 33 tests passing with 85.95% coverage (exceeds 85% requirement) - Comprehensive test coverage for all authentication scenarios Files Changed: - apps/api/src/websocket/websocket.gateway.ts (authentication logic) - apps/api/src/websocket/websocket.gateway.spec.ts (comprehensive tests) - apps/api/src/websocket/websocket.module.ts (dependency injection) - docs/scratchpads/198-strengthen-websocket-auth.md (documentation) Fixes #198 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
165
docs/scratchpads/198-strengthen-websocket-auth.md
Normal file
165
docs/scratchpads/198-strengthen-websocket-auth.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Issue #198: Strengthen WebSocket Authentication
|
||||
|
||||
## Objective
|
||||
Strengthen WebSocket authentication to prevent unauthorized access by implementing proper token validation, connection timeouts, rate limiting, and workspace access verification.
|
||||
|
||||
## Security Concerns
|
||||
- Unauthorized access to real-time updates
|
||||
- Missing authentication on WebSocket connections
|
||||
- No rate limiting allowing potential DoS
|
||||
- Lack of workspace access validation
|
||||
- Missing connection timeouts for unauthenticated sessions
|
||||
|
||||
## Approach
|
||||
1. Investigate current WebSocket/SSE implementation in apps/api/src/herald/
|
||||
2. Write comprehensive authentication tests (TDD approach)
|
||||
3. Implement authentication middleware:
|
||||
- Token validation on connection
|
||||
- Connection timeout for unauthenticated connections
|
||||
- Rate limiting per user
|
||||
- Workspace access permission verification
|
||||
4. Ensure all tests pass with ≥85% coverage
|
||||
5. Document security improvements
|
||||
|
||||
## Progress
|
||||
- [x] Create scratchpad
|
||||
- [x] Investigate current implementation
|
||||
- [x] Write failing authentication tests (RED)
|
||||
- [x] Implement authentication middleware (GREEN)
|
||||
- [x] Add connection timeout
|
||||
- [x] Add workspace validation
|
||||
- [x] Verify all tests pass (33/33 passing)
|
||||
- [x] Verify coverage ≥85% (achieved 85.95%)
|
||||
- [x] Document security review
|
||||
- [ ] Commit changes
|
||||
|
||||
## Testing
|
||||
- Unit tests for authentication middleware ✅
|
||||
- Integration tests for connection flow ✅
|
||||
- Workspace access validation tests ✅
|
||||
- Coverage verification: **85.95%** (exceeds 85% requirement) ✅
|
||||
|
||||
**Test Results:**
|
||||
- 33 tests passing
|
||||
- All authentication scenarios covered:
|
||||
- Valid token authentication
|
||||
- Invalid token rejection
|
||||
- Missing token rejection
|
||||
- Token verification errors
|
||||
- Connection timeout mechanism
|
||||
- Workspace access validation
|
||||
- Unauthorized workspace disconnection
|
||||
|
||||
## Notes
|
||||
|
||||
### Investigation Findings
|
||||
|
||||
**Current Implementation Analysis:**
|
||||
1. **WebSocket Gateway** (`apps/api/src/websocket/websocket.gateway.ts`)
|
||||
- Uses Socket.IO with NestJS WebSocket decorators
|
||||
- `handleConnection()` checks for `userId` and `workspaceId` in `socket.data`
|
||||
- Disconnects clients without these properties
|
||||
- **CRITICAL WEAKNESS**: No actual token validation - assumes `socket.data` is pre-populated
|
||||
- No connection timeout for unauthenticated connections
|
||||
- No rate limiting
|
||||
- No workspace access permission validation
|
||||
|
||||
2. **Authentication Service** (`apps/api/src/auth/auth.service.ts`)
|
||||
- Uses BetterAuth with session tokens
|
||||
- `verifySession(token)` validates Bearer tokens
|
||||
- Returns user and session data if valid
|
||||
- Can be reused for WebSocket authentication
|
||||
|
||||
3. **Auth Guard** (`apps/api/src/auth/guards/auth.guard.ts`)
|
||||
- Extracts Bearer token from Authorization header
|
||||
- Validates via `authService.verifySession()`
|
||||
- Throws UnauthorizedException if invalid
|
||||
- Pattern can be adapted for WebSocket middleware
|
||||
|
||||
**Security Issues Identified:**
|
||||
1. No authentication middleware on Socket.IO connections
|
||||
2. Clients can connect without providing tokens
|
||||
3. `socket.data` is not validated or populated from tokens
|
||||
4. No connection timeout enforcement
|
||||
5. No rate limiting (DoS risk)
|
||||
6. No workspace membership validation
|
||||
7. Clients can join any workspace room without verification
|
||||
|
||||
**Implementation Plan:**
|
||||
1. ✅ Create Socket.IO authentication middleware
|
||||
2. ✅ Extract and validate Bearer token from handshake
|
||||
3. ✅ Populate `socket.data.userId` and `socket.data.workspaceId` from validated session
|
||||
4. ✅ Add connection timeout for unauthenticated connections (5 seconds)
|
||||
5. ⚠️ Rate limiting (deferred - can be added in future enhancement)
|
||||
6. ✅ Add workspace access validation before allowing room joins
|
||||
7. ✅ Add comprehensive tests following TDD protocol
|
||||
|
||||
**Implementation Summary:**
|
||||
|
||||
### Changes Made
|
||||
|
||||
1. **WebSocket Gateway** (`apps/api/src/websocket/websocket.gateway.ts`)
|
||||
- Added `AuthService` and `PrismaService` dependencies via constructor injection
|
||||
- Implemented `extractTokenFromHandshake()` to extract Bearer tokens from:
|
||||
- `handshake.auth.token` (preferred)
|
||||
- `handshake.query.token` (fallback)
|
||||
- `handshake.headers.authorization` (fallback)
|
||||
- Enhanced `handleConnection()` with:
|
||||
- Token extraction and validation
|
||||
- Session verification via `authService.verifySession()`
|
||||
- Workspace membership validation via Prisma
|
||||
- Connection timeout (5 seconds) for slow/failed authentication
|
||||
- Proper cleanup on authentication failures
|
||||
- Populated `socket.data.userId` and `socket.data.workspaceId` from validated session
|
||||
|
||||
2. **WebSocket Module** (`apps/api/src/websocket/websocket.module.ts`)
|
||||
- Added `AuthModule` and `PrismaModule` imports
|
||||
- Updated module documentation
|
||||
|
||||
3. **Tests** (`apps/api/src/websocket/websocket.gateway.spec.ts`)
|
||||
- Added comprehensive authentication test suite
|
||||
- Tests for valid token authentication
|
||||
- Tests for invalid/missing token scenarios
|
||||
- Tests for workspace access validation
|
||||
- Tests for connection timeout mechanism
|
||||
- All 33 tests passing with 85.95% coverage
|
||||
|
||||
### Security Improvements Achieved
|
||||
|
||||
✅ **Token Validation**: All connections now require valid authentication tokens
|
||||
✅ **Session Verification**: Tokens verified against BetterAuth session store
|
||||
✅ **Workspace Authorization**: Users can only join workspaces they have access to
|
||||
✅ **Connection Timeout**: 5-second timeout prevents resource exhaustion
|
||||
✅ **Multiple Token Sources**: Supports standard token passing methods
|
||||
✅ **Proper Error Handling**: All authentication failures disconnect client immediately
|
||||
|
||||
### Rate Limiting Note
|
||||
|
||||
Rate limiting was not implemented in this iteration because:
|
||||
- It requires Redis/Valkey infrastructure setup
|
||||
- Socket.IO connections are already protected by token authentication
|
||||
- Can be added as a future enhancement when needed
|
||||
- Current implementation prevents basic DoS via authentication requirements
|
||||
|
||||
### Security Review
|
||||
|
||||
**Before:**
|
||||
- No authentication on WebSocket connections
|
||||
- Clients could connect without tokens
|
||||
- No workspace access validation
|
||||
- No connection timeouts
|
||||
- High risk of unauthorized access
|
||||
|
||||
**After:**
|
||||
- Strong authentication required
|
||||
- Token verification on every connection
|
||||
- Workspace membership validated
|
||||
- Connection timeouts prevent resource exhaustion
|
||||
- Low risk - properly secured
|
||||
|
||||
**Threat Model:**
|
||||
1. ❌ Anonymous connections → ✅ Blocked by token requirement
|
||||
2. ❌ Invalid tokens → ✅ Blocked by session verification
|
||||
3. ❌ Cross-workspace access → ✅ Blocked by membership validation
|
||||
4. ❌ Slow DoS attacks → ✅ Mitigated by connection timeout
|
||||
5. ⚠️ High-frequency DoS → ⚠️ Future: Add rate limiting if needed
|
||||
Reference in New Issue
Block a user