Skip to content

[FEATURE][SECURITY]: CSRF token protection system #543

@crivetimihai

Description

@crivetimihai

[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?

  1. Security Compliance: OWASP Top 10 requires CSRF protection for authenticated applications
  2. Enterprise Requirements: SOC2, HIPAA, and other compliance frameworks mandate CSRF protection
  3. Admin UI Exposure: The Admin UI performs sensitive operations (create/delete servers, manage users)
  4. 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 occur

Technical 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 token

Technical Requirements:

  • Set CSRF cookie with httponly=false for 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 pass

Technical Requirements:

  • CSRF_ENABLED toggle (default: true in production)
  • CSRF_TOKEN_EXPIRY in seconds (default: 3600)
  • CSRF_TRUSTED_ORIGINS for cross-origin deployments
  • CSRF_EXEMPT_PATHS for 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 response

Technical 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
Loading

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]
Loading

📋 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 to admin.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-token endpoint 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

  1. Enable CSRF protection: CSRF_ENABLED=true
  2. Update frontend to use fetchWithCSRF() wrapper
  3. Add CSRF tokens to all forms
  4. Configure trusted origins for cross-origin deployments
  5. Test all state-changing operations

🔗 Related Issues

Metadata

Metadata

Assignees

Labels

MUSTP1: Non-negotiable, critical requirements without which the product is non-functional or unsafeenhancementNew feature or requestpythonPython / backend development (FastAPI)readyValidated, ready-to-work-on itemssecurityImproves security

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions