Configure CSRF (Cross-Site Request Forgery) protection to prevent unauthorized actions from malicious websites.

[server.csrf] enabled = true header_name = "X-CSRF-Token"
  • enabled: Whether CSRF protection is enabled (default: false)
  • header_name: The header name to use for CSRF tokens (default: "X-Nexus-CSRF-Protection")

When enabled, Nexus will require this header to be present on every request.

  1. Client obtains a CSRF token (implementation-specific)
  2. Client includes token in the configured header
  3. Nexus validates the header is present
  4. Request proceeds if validation passes

The basic CSRF protection checks for header presence:

curl -X POST http://localhost:8000/llm/v1/chat/completions \ -H "Content-Type: application/json" \ -H "X-CSRF-Token: any-value" \ -d '{"model": "openai/gpt-4", "messages": [{"role": "user", "content": "Hello"}]}'
// Simple CSRF token implementation const csrfToken = 'your-csrf-token-here'; fetch('http://localhost:8000/llm/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken // Include CSRF token }, body: JSON.stringify({ model: 'openai/gpt-4', messages: [{ role: 'user', content: 'Hello' }] }) });
import { useState, useEffect } from 'react'; function ChatComponent() { const [csrfToken] = useState(() => { // Generate or retrieve token return crypto.randomUUID(); }); const sendMessage = async (message) => { const response = await fetch('/llm/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken }, body: JSON.stringify({ model: 'openai/gpt-4', messages: [{ role: 'user', content: message }] }) }); return response.json(); }; // ... rest of component }

CSRF and OAuth2 work together for defense in depth:

# OAuth2 for authentication [server.oauth] url = "https://auth.example.com/.well-known/jwks.json" expected_issuer = "https://auth.example.com" # CSRF for request validation [server.csrf] enabled = true header_name = "X-CSRF-Token"

Client must provide both:

fetch('/llm/v1/chat/completions', { method: 'POST', headers: { 'Authorization': 'Bearer ' + jwtToken, 'X-CSRF-Token': csrfToken, 'Content-Type': 'application/json' }, body: JSON.stringify(data) });

Configure both for browser security:

[server.cors] allow_origins = ["https://app.example.com"] allow_headers = ["authorization", "content-type", "x-csrf-token"] allow_credentials = true [server.csrf] enabled = true header_name = "X-CSRF-Token"

Use custom headers for compatibility:

# Django-style [server.csrf] enabled = true header_name = "X-CSRFToken" # Rails-style [server.csrf] enabled = true header_name = "X-CSRF-Token" # Custom [server.csrf] enabled = true header_name = "X-Request-Token"
  • Serving browser-based clients
  • Handling sensitive operations
  • Compliance requirements mandate it
  • API is consumed only by non-browser clients
  • Using only OAuth2 bearer tokens
  • No state-changing operations
  • Internal APIs with no browser access

When CSRF validation fails:

HTTP/1.1 403 Forbidden
  • Verify header name matches configuration exactly
  • Check that header is included in CORS allow_headers
  • Ensure header value is not empty
  • Confirm header is sent with request
  • Test with curl to isolate browser issues
  • Check browser developer tools for header presence
  • Verify CORS configuration allows the CSRF header
  • Review server logs for specific error details
© Grafbase, Inc.