mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-22 03:02:35 +00:00
This commit addresses 5 critical P0 bugs that cause security vulnerabilities, crashes, and data corruption: **P0-1: Recovery Tokens Replay Attack Vulnerability** (recovery_tokens.go:153-159) - **SECURITY CRITICAL**: Single-use recovery tokens could be replayed - **Problem**: Lock upgrade race - two concurrent requests both pass initial Used check 1. Both acquire RLock, see token.Used = false 2. Both release RLock 3. Both acquire Lock and mark token.Used = true 4. Both return true - TOKEN REUSED - **Impact**: Attacker with intercepted token can use it multiple times - **Fix**: Re-check token.Used after acquiring write lock (TOCTOU prevention) **P0-2: WebSocket Hub Concurrent Map Panic** (hub.go:345-347, 376-378) - **Problem**: Initial state goroutine reads h.clients map without lock - Line 345: `if _, ok := h.clients[client]` (NO LOCK) - Main loop writes to h.clients with lock (line 326, 394) - **Impact**: "fatal error: concurrent map read and write" crashes hub - **Fix**: Acquire RLock before all client map reads in goroutine **P0-3: WebSocket Send on Closed Channel Panic** (hub.go:348, 380) - **Problem**: Check client exists, then send - channel can close between - **Impact**: "send on closed channel" panic crashes hub - **Fix**: Hold RLock during both check and send (defensive select already present) **P0-4: CSRF Store Shutdown Data Corruption** (csrf_store.go:189-196) - **Problem**: Stop() calls save() after signaling worker. Both hold only RLock - Worker's final save writes to csrf_tokens.json.tmp - Stop()'s save writes to same file concurrently - **Impact**: Corrupted/truncated csrf_tokens.json on shutdown - **Fix**: Added saveMu mutex to serialize all disk writes **P0-5: CSRF Store Deadlock on Double-Stop** (csrf_store.go:103-108) - **Problem**: stopChan unbuffered, no sync.Once guard, uses send not close - **Impact**: Second Stop() call blocks forever waiting for receiver - **Fix**: - Added sync.Once field stopOnce - Changed to close(stopChan) within stopOnce.Do() - Prevents double-close panic and deadlock All fixes maintain backwards compatibility. The recovery token fix is particularly critical as it closes a security vulnerability allowing replay attacks on password reset flows. |
||
|---|---|---|
| .. | ||
| alerts.go | ||
| alerts_test.go | ||
| auth.go | ||
| auth_scope_test.go | ||
| bootstrap_token.go | ||
| config_handlers.go | ||
| config_handlers_auto_register_test.go | ||
| config_handlers_cluster_test.go | ||
| config_handlers_setup_script_test.go | ||
| csrf_store.go | ||
| demo_middleware.go | ||
| diagnostics.go | ||
| DO_NOT_EDIT_FRONTEND_HERE.md | ||
| docker_agents.go | ||
| docker_metadata.go | ||
| frontend_embed.go | ||
| guest_metadata.go | ||
| host_agents.go | ||
| host_agents_test.go | ||
| http_metrics.go | ||
| middleware.go | ||
| notification_queue.go | ||
| notifications.go | ||
| oidc_handlers.go | ||
| oidc_service.go | ||
| rate_limit_config.go | ||
| rate_limit_config_test.go | ||
| ratelimit.go | ||
| README.md | ||
| recovery_tokens.go | ||
| router.go | ||
| router_integration_test.go | ||
| security.go | ||
| security_oidc.go | ||
| security_setup_fix.go | ||
| security_setup_fix_test.go | ||
| security_test.go | ||
| security_tokens.go | ||
| security_tokens_test.go | ||
| session_store.go | ||
| system_settings.go | ||
| types.go | ||
| updates.go | ||
Internal API Package
This directory contains the API server implementation for Pulse.
Important Note About frontend-modern/
The frontend-modern/ subdirectory that appears here is:
- AUTO-GENERATED during builds
- NOT the source code - just a build artifact
- IN .gitignore - never committed
- REQUIRED BY GO - The embed directive needs it here
Frontend Development Location
👉 Edit frontend files at: /opt/pulse/frontend-modern/src/
Why This Structure?
Go's //go:embed directive has limitations:
- Cannot use
../paths to access parent directories - Cannot follow symbolic links
- Must embed files within the Go module
This is a known Go limitation and our structure works around it.