Jason Woltje
ebd842f007
ci/woodpecker/push/woodpecker Pipeline failed
fix(#278): Implement CSRF protection using double-submit cookie pattern
Implemented comprehensive CSRF protection for all state-changing endpoints
(POST, PATCH, DELETE) using the double-submit cookie pattern.
Security Implementation:
- Created CsrfGuard using double-submit cookie validation
- Token set in httpOnly cookie and validated against X-CSRF-Token header
- Applied guard to FederationController (vulnerable endpoints)
- Safe HTTP methods (GET, HEAD, OPTIONS) automatically exempted
- Signature-based endpoints (@SkipCsrf decorator) exempted
Components Added:
- CsrfGuard: Validates cookie and header token match
- CsrfController: GET /api/v1/csrf/token endpoint for token generation
- @SkipCsrf(): Decorator to exempt endpoints with alternative auth
- Comprehensive tests (20 tests, all passing)
Protected Endpoints:
- POST /api/v1/federation/connections/initiate
- POST /api/v1/federation/connections/:id/accept
- POST /api/v1/federation/connections/:id/reject
- POST /api/v1/federation/connections/:id/disconnect
- POST /api/v1/federation/instance/regenerate-keys
Exempted Endpoints:
- POST /api/v1/federation/incoming/connect (signature-verified)
- GET requests (safe methods)
Security Features:
- httpOnly cookies prevent XSS attacks
- SameSite=strict prevents subdomain attacks
- Cryptographically secure random tokens (32 bytes)
- 24-hour token expiry
- Structured logging for security events
Testing:
- 14 guard tests covering all scenarios
- 6 controller tests for token generation
- Quality gates: lint, typecheck, build all passing
Note: Frontend integration required to use tokens. Clients must:
1. GET /api/v1/csrf/token to receive token
2. Include token in X-CSRF-Token header for state-changing requests
Fixes #278
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 20:35:00 -06:00
..
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 20:24:41 -06:00
2026-02-03 19:17:13 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 15:27:00 -06:00
2026-02-02 15:27:00 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 12:34:24 -06:00
2026-02-03 12:55:37 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 13:45:00 -06:00
2026-02-03 14:03:44 -06:00
2026-02-03 14:18:18 -06:00
2026-02-03 14:51:59 -06:00
2026-02-03 14:51:59 -06:00
2026-01-31 11:38:38 -06:00
2026-01-31 12:10:43 -06:00
2026-01-31 12:22:14 -06:00
2026-01-31 11:57:40 -06:00
2026-02-01 17:56:04 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:22:07 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:56:45 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 21:01:25 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:26:40 -06:00
2026-02-01 21:32:53 -06:00
2026-02-01 21:42:44 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 08:18:55 -06:00
2026-02-01 21:44:04 -06:00
2026-02-01 21:54:34 -06:00
2026-02-01 20:54:25 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 20:54:57 -06:00
2026-02-02 11:41:11 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 12:51:17 -06:00
2026-02-02 12:41:12 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 12:30:19 -06:00
2026-02-02 12:03:36 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 12:51:17 -06:00
2026-02-02 12:55:17 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 16:50:06 -06:00
2026-02-03 18:58:00 -06:00
2026-02-03 19:53:09 -06:00
2026-02-03 20:17:47 -06:00
2026-02-03 20:21:06 -06:00
2026-02-03 20:24:46 -06:00
2026-02-03 20:27:45 -06:00
2026-02-03 20:35:00 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00