feat: implement CSRF protection using server-side tokens #WP-186#1
Merged
Conversation
Implements Cross-Site Request Forgery (CSRF) protection following industry best practices and security guidelines: ## Implementation Details ### Architecture - **Token Generation**: Cryptographically secure random tokens (256 bits) generated per session using crypto/rand - **Server-Side Storage**: Tokens stored in PostgreSQL sessions table tied to user sessions for immediate revocation capability - **Constant-Time Verification**: Uses hmac.Equal() to prevent timing attacks ### Components Added 1. **internal/security/csrf.go**: Token manager for secure random generation - Generates 64-character hex tokens (256 bits) - No database lookups during verification (done by middleware) 2. **internal/middleware/csrf.go**: CSRF validation middleware - Validates on state-changing requests (POST, PUT, DELETE, PATCH) - Skips safe methods (GET, HEAD, OPTIONS) - Exempts endpoints: /health, /metrics, /ws/* (WebSocket uses different auth) - Extracts tokens from: form data, X-CSRF-Token header, X-XSRF-Token header - Logs security events on validation failure with context (user_id, method, path) 3. **internal/middleware/csrf_test.go**: Comprehensive middleware tests - Tests token validation from multiple sources - Tests security event logging - Tests exemption of safe methods and endpoints ### Database Changes - Migration 000003: Adds csrf_token column to sessions table - Unique constraint prevents token reuse across sessions - Index on csrf_token for efficient validation ### Session Management - Session struct now includes CSRFToken field - SessionRepository extended with: - GetByCSRFToken(): Retrieve session by CSRF token - UpdateCSRFToken(): Associate token with session ### Auth Handler Integration - Generates CSRF token on successful login - Returns token in LoginResponse JSON - Token stored server-side for immediate revocation on logout ### Frontend Integration - Login/Register: Store CSRF token in sessionStorage - sessionStorage chosen over localStorage (cleared on tab close) - Safer than localStorage (XSS vulnerable) - API Calls: Include token in X-CSRF-Token header for all state-changing requests - Helper function added to index.html for consistent token handling ## Security Properties ✓ **Prevents cross-site request forgery** from attacker-controlled domains ✓ **Tokens tied to session** - invalidated on logout/session expiration ✓ **Stateless verification possible** but implemented server-side for: - Immediate revocation capability - Better logging and monitoring - Scales to load-balanced deployments (shared PostgreSQL) ✓ **Constant-time comparison** prevents timing attacks ✓ **Security event logging** for monitoring and alerting ✓ **SameSite cookie** attribute already set (Lax mode) ✓ **No token leakage** - never in URLs or cookies alone ## Complementary Protections - Rate limiting on auth endpoints (already implemented) - HTTPS enforcement (configure in deployment) - CORS policies (already implemented) - Session timeout (already implemented) ## Testing - Unit tests for token generation (uniqueness, format, entropy) - Integration tests for middleware (validation, exemption, logging) - All existing tests updated and passing - Handler and service tests updated with mock CSRF methods ## Notes - Implementation uses per-session tokens (simpler than per-request) - WebSocket endpoints exempt from CSRF (use session token in query param) - Tokens persist for session lifetime (no per-request rotation)
dvrd
force-pushed
the
feat/csrf-protection
branch
2 times, most recently
from
February 2, 2026 22:48
ea62b71 to
47452af
Compare
Implements comprehensive CI/CD pipeline for automated quality checks: Runs on: - Push to main, develop, and feat/** branches 1. **Test** - Runs go test with race detector and coverage - Uses PostgreSQL 15 service for database tests - Reports coverage to codecov - Parallel test execution with -race flag 2. **Lint** - Runs golangci-lint - Checks code quality with strict rules - Detects issues like unused variables, incorrect error handling - Enforces security best practices 3. **Format Check** - Verifies code formatting - gofmt compliance (simplified syntax -s) - goimports import organization - Fails if formatting incorrect (auto-fixable with make fmt-fix) 4. **Vet** - Runs go vet - Static analysis for suspicious code - Type checking and common mistakes - No-op code detection 5. **Build** - Builds both binaries - chat-server build - stock-bot build - Ensures code compiles successfully
dvrd
force-pushed
the
feat/csrf-protection
branch
from
February 2, 2026 23:14
47452af to
faa19b9
Compare
- Add pre-push hook to run linting before pushes - Configure git to use .githooks directory for all team members - Add setup-hooks.sh script for easy hook installation - Ensures code quality standards are enforced locally
- Fix unused struct fields (remove unused mu sync.Mutex) - Fix error shadowing by renaming duplicate error variables - Fix unchecked error returns with _ assignments or proper handling - Fix integer overflow in bit shift operations - Fix string comparison with empty string instead of len() - Combine identical parameter types in function signatures - Add nolint comments for intentional warnings (exitAfterDefer, gosec) - Add test helper annotations (nolint:unused) for mock structures - Fix empty branch in switch statement by using blank identifier - Remove unused helper functions (createMockCSV) - Refactor if-else chains to switch statements where appropriate All 124 initial linting errors resolved.
- Replace deprecated 'golint' linter with 'revive' - Remove deprecated linters from disabled list (exhaustivestruct, gomnd) - Remove redundant enabled checks in gocritic (use defaults) - Simplify configuration to only specify custom checks Resolves all golangci-lint warnings. Clean output with no warnings or errors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements Cross-Site Request Forgery (CSRF) protection following industry best
practices and security guidelines:
Implementation Details
Architecture
per session using crypto/rand
sessions for immediate revocation capability
Components Added
internal/security/csrf.go: Token manager for secure random generation
internal/middleware/csrf.go: CSRF validation middleware
internal/middleware/csrf_test.go: Comprehensive middleware tests
Database Changes
Session Management
Auth Handler Integration
Frontend Integration
Security Properties
✓ Prevents cross-site request forgery from attacker-controlled domains
✓ Tokens tied to session - invalidated on logout/session expiration
✓ Stateless verification possible but implemented server-side for:
✓ Constant-time comparison prevents timing attacks
✓ Security event logging for monitoring and alerting
✓ SameSite cookie attribute already set (Lax mode)
✓ No token leakage - never in URLs or cookies alone
Complementary Protections
Testing
Notes