2.5 KiB
2.5 KiB
09. Fix WebSocket no Origin header validation
meta: id: security-fixes-09 feature: security-fixes priority: P1 depends_on: [security-fixes-08] tags: [implementation, tests-required, medium-severity]
objective:
- Prevent cross-origin WebSocket connections by validating the Origin header during the upgrade handshake
deliverables:
verifyClientcallback on the WebSocket server that validates the Origin header- Configurable allowlist of trusted origins for WebSocket connections
- Unit tests for Origin validation
steps:
- Examine
web/src/server/websocket.ts:80-102(WebSocketServer constructor and connection handler) - Add a
verifyClientcallback to theWebSocketServerconstructor:- Extract the
Originheader from the upgrade request - Validate against a trusted origins allowlist (derived from
APP_URLand localhost) - Reject connections with missing or untrusted Origin headers
- Extract the
- Define the trusted origins allowlist:
http://localhost:3000,http://localhost:3001(development)APP_URL(production, validated per task 05)- Optional:
VALID_WEBSOCKET_ORIGINSenv var for explicit configuration
- Ensure the Origin validation works with the post-connection auth flow from task 08
- Log rejected connections for monitoring
tests:
- Unit: Connection from trusted origin (
localhost:3000) is accepted - Unit: Connection from untrusted origin (
https://evil.com) is rejected - Unit: Connection without an Origin header is rejected
- Integration: WebSocket connection from a trusted page succeeds
- Integration: WebSocket connection initiated from an untrusted page (via
<script>) is rejected
acceptance_criteria:
- WebSocket server validates the Origin header during the upgrade handshake
- Connections from untrusted origins are rejected before authentication
- Trusted origins include localhost (dev) and APP_URL (production)
- Missing Origin headers are rejected
- The Origin validation complements the JWT authentication from task 08
validation:
cd web && bun test— all tests pass- Connect from a trusted origin and verify the connection is accepted
- Attempt to connect from an untrusted origin and verify it is rejected
- Check server logs for rejected connection entries
notes:
- Finding p8-009: The WebSocket server on port 3001 has no Origin validation
- Depends on task 08 because the authentication flow needs to be established first
- The
verifyClientcallback receives{ origin, req, secure }— useoriginfor validation - Combined with task 08 (JWT auth), this closes the complete authentication bypass chain