How CSRF protection works
Kratos uses the double submit cookie pattern for CSRF protection:- When a flow is initialized, Kratos generates a CSRF token
- The token is:
- Stored in a cookie (
ory_csrf_[flow_type]) - Included in the flow UI (
csrf_tokenfield)
- Stored in a cookie (
- When submitting the flow, both the cookie and form field must match
- Kratos validates the token server-side before processing the request
CSRF tokens are flow-specific and time-bound. Each flow type (login, registration, etc.) has its own CSRF token.
Browser flows
For browser-based flows, CSRF protection is automatic:Flow initialization
When you initialize a flow:Flow submission
Include the CSRF token when submitting:API flows
API flows (native mobile apps, SPAs without cookies) do not use CSRF protection because:- They use token-based authentication
- They cannot be targeted by browser-based CSRF attacks
- Same-origin policy doesn’t apply
CSRF cookie configuration
Configure CSRF cookies in your Kratos configuration:Cookie domain. Use your root domain (e.g.,
example.com) to share cookies across subdomains.SameSite attribute:
Strict: Most secure, blocks all cross-site requestsLax: Balances security and usability (recommended)None: Allows cross-site requests (requiressecure: true)
Only send cookies over HTTPS. Must be
true in production.SameSite cookie attributes
- Lax (Recommended)
- Strict
- None
- Cookies sent on top-level navigation (e.g., clicking a link)
- Cookies NOT sent on cross-site POST requests
- Prevents CSRF while allowing normal navigation
Frontend implementation
React example
Vue.js example
CSRF token errors
Common CSRF-related errors:400 Bad Request: CSRF token mismatch
400 Bad Request: CSRF token mismatch
Cause: Cookie token doesn’t match form tokenSolutions:
- Ensure cookies are enabled
- Check that
credentials: 'include'is set in fetch requests - Verify cookie domain matches your application domain
- Ensure HTTPS is used if
secure: true
400 Bad Request: Missing CSRF token
400 Bad Request: Missing CSRF token
Cause: CSRF token not included in requestSolutions:
- Extract
csrf_tokenfrom flow UI nodes - Include token in request body
- Ensure you’re using browser flow (not API flow)
Cookies not being set
Cookies not being set
Development mode
The--dev flag disables CSRF protection:
Security considerations
Configure SameSite correctly
Use
Lax or Strict for maximum protection. Only use None if you need cross-site authentication.Validate on the server
Never rely solely on client-side CSRF checks. Kratos validates all tokens server-side.
Troubleshooting
Debug CSRF issues
Enable trace logging to see CSRF validation:- Open DevTools → Application → Cookies
- Look for
ory_csrf_*cookies - Verify cookie attributes (Secure, SameSite, Domain)
Test CSRF protection
Verify CSRF is working:Next steps
Best practices
Security hardening guide
Rate limiting
Protect against brute force