Draft implementation PR: https://github.com/badbundle/track-slash/pull/97
Description
Problem
WebSocket origin validation explicitly permits every origin when CORS_ALLOWED_ORIGINS is empty (internal/realtime/ws.go:16-28, :40-56). Server construction documents that the empty default leaves WebSockets open for development (internal/server/server.go:33-35), and both the bearer-authenticated API socket and cookie-authenticated UI socket receive this same list.
The production deployment guide requires TRACK_SLASH_PUBLIC_ORIGIN but does not require CORS_ALLOWED_ORIGINS (DEPLOYMENT.md:59-65). As a result, a normal production configuration can retain the fail-open WebSocket policy.
Impact
A malicious browser origin that can send the user's cookie—most notably an untrusted same-site sibling origin—can establish the UI WebSocket as the victim and subscribe to authorized project topics. Topic authorization limits the blast radius to the victim's access, but cross-site event observation and traffic analysis remain possible.
Acceptance criteria
- Derive the browser WebSocket allow-list from the validated public origin independently of whether cross-origin API CORS is enabled.
- Fail closed for non-empty browser
Originvalues in deployed mode; make permissive localhost development explicit. - Keep a documented path for non-browser bearer-token clients that omit
Origin. - Ensure API and UI WebSocket endpoints use the intended, separately testable policy.
- Add tests for default production config, allowed same-origin, rejected foreign/sibling origin, empty non-browser Origin, and localhost development.
- Update deployment documentation so a secure production default does not depend on an optional CORS variable.
Sub-issues
0Linked issues
0GitHub
0No branches or pull requests linked.