Files
OwnCord/Server/ws/origin.go
T
jevb a40b42bbed fix: resolve 24 critical and high issues from full code & security review
CRITICAL (5):
- Hub panic recovery now calls h.Stop() after 3 panics (ws/hub.go)
- Ring buffer EventsSince returns non-nil empty slice for current seq (ws/ringbuffer.go)
- PTT event listener stores unsubscribe handle to prevent leak (ptt.ts)
- verifyTotp respects config.allowSelfSigned instead of hardcoding (api.ts)
- ptt_listen_for_key uses spawn_blocking to avoid thread pool starvation (ptt.rs)

HIGH - Server (13):
- TOTP rate-limit checked after body decode; counters reset on success
- TOTP enable returns 409 if already enabled (must disable first)
- Global search pre-computes accessible channel IDs for FTS WHERE clause
- DeleteAccount queries roles by name instead of hard-coded IDs
- BackupToSafe uses absClean in VACUUM INTO
- Voice camera slot uses atomic EnableCameraIfUnderLimit DB method
- readPump snapshots voiceChID before unregister for TOCTOU safety
- Voice join sets state after token send; rollback takes broadcast flag
- Updater download uses probe pattern instead of overflow write
- Webhook checks Authorization header before reading body
- Storage.Save adds fsync and fixes double-close
- Default WS origin denies cross-origin (was: accept all)

HIGH - Client (6):
- WS reconnect uses generation counter to discard stale events
- AudioPipeline uses generation counter against stale worklet callbacks
- Screenshare mute state preserved across reconnect (not full leave)
- handleVoiceToken uses iterative loop instead of unbounded recursion
- store.ts re-entrancy guard with pending update queue
- Notification AudioContext cleaned up on logout

Reviewed by 4 parallel agents across Server Core, Server Realtime,
Client & Tauri, and Security. 55 total findings; 24 CRITICAL+HIGH
fixed here, 31 MEDIUM+LOW tracked in vault backlog (T-265–T-295).
2026-04-01 09:23:17 +02:00

37 lines
1.3 KiB
Go

package ws
import (
"log/slog"
"nhooyr.io/websocket"
)
// OriginAcceptOptions builds a *websocket.AcceptOptions that enforces origin
// checking according to the provided allowed-origins list.
//
// Rules:
// - nil or empty list → InsecureSkipVerify = false (deny all cross-origin; safe default)
// - list contains "*" → InsecureSkipVerify = true (explicit opt-in for any origin)
// - any other list → OriginPatterns set to the list; origin checking active
//
// The Tauri desktop client uses a Rust WS proxy that does not send an Origin
// header, so the default deny-all does not block desktop connections.
// Set allowed_origins: ["*"] in config to explicitly allow any origin.
func OriginAcceptOptions(allowedOrigins []string) *websocket.AcceptOptions {
if len(allowedOrigins) == 0 {
slog.Info("ws: no allowed_origins configured — denying cross-origin connections (safe default)")
return &websocket.AcceptOptions{InsecureSkipVerify: false}
}
for _, o := range allowedOrigins {
if o == "*" {
slog.Warn("ws: allowed_origins contains wildcard '*' — accepting connections from ANY origin (insecure)")
return &websocket.AcceptOptions{InsecureSkipVerify: true}
}
}
return &websocket.AcceptOptions{
OriginPatterns: allowedOrigins,
}
}