-
Notifications
You must be signed in to change notification settings - Fork 613
[FEATURE][SECURITY]: CSRF token protection system #543
Description
[FEATURE][SECURITY]: CSRF Token Protection System
Goal
Implement comprehensive CSRF (Cross-Site Request Forgery) protection for all state-changing operations in MCP Gateway. This includes double-submit cookie pattern, per-session tokens, SameSite cookies, and automatic token validation for forms and API requests.
Why Now?
- Security Compliance: OWASP Top 10 requires CSRF protection for authenticated applications
- Enterprise Requirements: SOC2, HIPAA, and other compliance frameworks mandate CSRF protection
- Admin UI Exposure: The Admin UI performs sensitive operations (create/delete servers, manage users)
- Defense in Depth: JWT authentication alone doesn't prevent CSRF attacks from authenticated sessions
📖 User Stories
US-1: Security - Protect State-Changing Operations
As a security engineer
I want all POST/PUT/DELETE requests to require CSRF tokens
So that attackers cannot forge requests from authenticated users
Acceptance Criteria:
Scenario: CSRF token required for mutations
Given I am authenticated as an admin
When I submit a POST request without CSRF token
Then the request should be rejected with 403 Forbidden
And the response should indicate "CSRF token missing"
Scenario: Valid CSRF token allows request
Given I am authenticated as an admin
And I have obtained a CSRF token
When I submit a POST request with valid CSRF token in header
Then the request should be processed normally
Scenario: Safe methods exempt
Given I am authenticated as an admin
When I submit a GET request without CSRF token
Then the request should succeed
And no CSRF validation should occurTechnical Requirements:
- Validate CSRF token on POST, PUT, DELETE, PATCH methods
- Skip validation for GET, HEAD, OPTIONS, TRACE
- Return 403 with clear error message on failure
US-2: Frontend - Automatic CSRF Token Handling
As a frontend developer
I want CSRF tokens automatically included in requests
So that I don't need to manually manage tokens
Acceptance Criteria:
Scenario: Token in cookie readable by JavaScript
Given I log into the Admin UI
Then a CSRF token cookie should be set
And the cookie should be accessible to JavaScript (httponly=false)
Scenario: Automatic token inclusion
Given I have a valid CSRF token in cookie
When I use fetch() to make a POST request
Then the X-CSRF-Token header should be automatically included
Scenario: Token refresh on expiration
Given my CSRF token has expired
When I make a POST request
Then a new token should be fetched automatically
And the request should be retried with the new tokenTechnical Requirements:
- Set CSRF cookie with
httponly=falsefor JS access - Provide
fetchWithCSRF()wrapper function - Handle 403 errors with automatic token refresh and retry
US-3: Admin - Configure CSRF Protection
As a platform administrator
I want to configure CSRF protection behavior
So that I can tune it for my deployment
Acceptance Criteria:
Scenario: Disable CSRF for development
Given CSRF_ENABLED=false
When I make a POST request without CSRF token
Then the request should succeed
Scenario: Configure token expiry
Given CSRF_TOKEN_EXPIRY=7200
When a CSRF token is generated
Then it should be valid for 2 hours (7200 seconds)
Scenario: Add trusted origins
Given CSRF_TRUSTED_ORIGINS=https://app.example.com
When a request comes from https://app.example.com
And the referer header matches the trusted origin
Then CSRF validation should passTechnical Requirements:
CSRF_ENABLEDtoggle (default: true in production)CSRF_TOKEN_EXPIRYin seconds (default: 3600)CSRF_TRUSTED_ORIGINSfor cross-origin deploymentsCSRF_EXEMPT_PATHSfor public endpoints
US-4: Security - Token Binding and Rotation
As a security engineer
I want CSRF tokens bound to user sessions and rotated regularly
So that stolen tokens have limited usefulness
Acceptance Criteria:
Scenario: Token bound to session
Given user Alice has CSRF token "token-A"
When user Bob tries to use "token-A"
Then the request should be rejected
Because the token is bound to Alice's session
Scenario: Token rotation on login
Given CSRF_ROTATE_ON_LOGIN=true
When a user logs in
Then a new CSRF token should be generated
And the old token should be invalidated
Scenario: Token rotation on error
Given CSRF_ROTATE_ON_ERROR=true
When a request returns 4xx or 5xx error
Then the CSRF token should be rotated
And a new token should be set in the responseTechnical Requirements:
- Bind token to user_id and session_id
- Rotate tokens on login
- Optional rotation on errors
- Use HMAC for token integrity
🏗 Architecture
CSRF Validation Flow
sequenceDiagram
participant Client
participant Middleware as CSRF Middleware
participant Service
participant DB
Client->>Middleware: POST /admin/gateways
Middleware->>Middleware: Check method (POST = requires CSRF)
Middleware->>Middleware: Extract token from header/cookie
alt Token Missing
Middleware-->>Client: 403 "CSRF token missing"
else Token Invalid
Middleware-->>Client: 403 "Invalid CSRF token"
else Token Valid
Middleware->>Service: Process request
Service->>DB: Execute operation
Service-->>Middleware: Response
Middleware-->>Client: Success + new token
end
Double-Submit Cookie Pattern
flowchart TD
A[Login] --> B[Generate CSRF Token]
B --> C[Set Cookie: csrf_token=xxx]
B --> D[Return Token in Response]
E[Subsequent Request] --> F{Method Safe?}
F -->|GET/HEAD| G[Skip Validation]
F -->|POST/PUT/DELETE| H[Extract Token]
H --> I[From Header: X-CSRF-Token]
H --> J[From Cookie: csrf_token]
I --> K{Tokens Match?}
J --> K
K -->|Yes| L[Process Request]
K -->|No| M[403 Forbidden]
📋 Implementation Tasks
Phase 1: CSRF Service
- Create
mcpgateway/services/csrf_service.py - Implement token generation with HMAC
- Implement token validation with session binding
- Add token cache with expiration
- Implement cookie management methods
Phase 2: CSRF Middleware
- Create
mcpgateway/middleware/csrf_middleware.py - Implement request interception
- Add method-based skip logic (safe methods)
- Add path-based exemptions
- Integrate with authentication
Phase 3: Configuration
- Add CSRF settings to
config.py - Document all settings in
.env.example - Add sensible defaults for production
Phase 4: Frontend Integration
- Add
getCSRFToken()function toadmin.js - Add
fetchWithCSRF()wrapper - Update all form submissions
- Implement automatic retry on 403
Phase 5: Authentication Integration
- Generate CSRF token on login
- Clear CSRF token on logout
- Add
/auth/csrf-tokenendpoint for token refresh - Rotate token on login if configured
Phase 6: Testing
- Unit tests for CSRF service
- Integration tests for middleware
- Frontend tests for token handling
- Security tests for bypass attempts
⚙️ Configuration Example
# CSRF Protection Settings
CSRF_ENABLED=true
# Token configuration
CSRF_TOKEN_NAME=X-CSRF-Token
CSRF_COOKIE_NAME=csrf_token
CSRF_TOKEN_LENGTH=32
CSRF_TOKEN_EXPIRY=3600 # 1 hour
# Cookie settings
CSRF_COOKIE_SECURE=true # HTTPS only
CSRF_COOKIE_HTTPONLY=false # JS must read
CSRF_COOKIE_SAMESITE=Strict
# Security settings
CSRF_CHECK_REFERER=true
CSRF_ROTATE_ON_LOGIN=true
CSRF_ROTATE_ON_ERROR=true
# Trusted origins (comma-separated)
CSRF_TRUSTED_ORIGINS=https://app.example.com,https://admin.example.com
# Exempted paths (comma-separated)
CSRF_EXEMPT_PATHS=/health,/auth/login,/auth/refresh,/docs,/openapi.json,/metrics✅ Success Criteria
- All POST/PUT/DELETE requests require valid CSRF token
- GET/HEAD/OPTIONS/TRACE requests bypass CSRF validation
- Admin UI automatically includes CSRF tokens
- Token validation binds to user session
- 403 responses include clear error messages
- Token rotation works on login and errors
- Configuration toggles work correctly
- No security bypasses found in testing
🏁 Definition of Done
- CSRF service implemented and tested
- CSRF middleware integrated
- Frontend updated with CSRF handling
- Configuration options documented
- Settings added to
.env.example - Unit tests with >90% coverage
- Integration tests pass
- Security testing complete
- Code passes
make verify - Documentation updated
📝 Additional Notes
Security Benefits
| Protection | Description |
|---|---|
| Double-Submit Cookie | Validates token in both cookie and header |
| Session Binding | Tokens tied to specific user sessions |
| Token Rotation | Limits window for stolen token abuse |
| Referer Validation | Additional check for request origin |
| SameSite Cookies | Browser-level CSRF protection |
Migration Guide
- Enable CSRF protection:
CSRF_ENABLED=true - Update frontend to use
fetchWithCSRF()wrapper - Add CSRF tokens to all forms
- Configure trusted origins for cross-origin deployments
- Test all state-changing operations
🔗 Related Issues
- Depends on: JWT authentication system
- Related: [FEATURE][SECURITY]: Enhanced session management for admin UI #541 (Enhanced session management)
- OWASP Reference: CSRF Prevention Cheat Sheet