CSRF Defense Configuration Checker
Work through how your app actually defends against cross-site request forgery - cookie attributes, tokens, origin checks - and find the gap between what you think is set and what is.
Runs locallyEverything happens in your browser. What you paste or drop here is never uploaded, logged or stored.
Use the tool
CSRF defence is layers, not a setting
Cross-site request forgery makes a logged-in user's browser send a state-changing request the user never intended. The browser attaches the session cookie automatically, so the request is authenticated - the only question is whether anything proves it came from your own page.
There is no single setting that answers that. What matters is whether the layers you have cover the request types your application actually accepts, and this tool works through that either as a questionnaire or by reading your configuration.
SameSite is not sufficient on its own
SameSite=Lax is now the browser default and it removes a large part of classic CSRF -
the cookie is withheld from cross-site subrequests. It is not a complete defence, for three specific
reasons:
- Lax still allows cross-site top-level GET. If any GET in your application changes state, it remains reachable from a link, a redirect, or a chat client's link preview.
- A same-site attacker is unaffected. SameSite treats every subdomain as the same site. A compromised subdomain, or user content served from your own origin, sits inside the boundary.
- Not every client enforces it. The default has changed once already, and older or unusual clients vary.
Unsigned double-submit has a specific weakness
The plain double-submit pattern compares a cookie value against a value in the request body. It is attractive because it needs no server-side state - and it fails against an attacker who can set a cookie on your domain.
That is not hypothetical: cookies are shared across subdomains in a way the same-origin policy is not. A compromised or hostile subdomain can set a cookie on the parent domain, so it sets both halves to a value it knows and the comparison passes.
The fix is to sign the token - HMAC it against the session - so its value cannot be forged. This tool distinguishes the two variants because the difference matters and is easy to miss.
The JSON assumption
A common belief is that an endpoint requiring Content-Type: application/json is immune,
because an HTML form cannot produce that content type. That is true only while nothing else does - and
a permissive CORS policy that allows the header, or an endpoint that also accepts form encoding,
removes it. The assumption tends to outlive the configuration that made it true.
Requiring a custom header is the robust version of the same idea. A custom header cannot be set cross-origin without a successful preflight, which is a real check rather than a side effect.
State-changing GET undermines everything else
If a GET request changes state, Lax permits it cross-site, tokens are usually only enforced on POST, and it can be triggered by an image tag, a prefetch or a link preview - none of which the user chose.
Making every state-changing operation a POST, PUT, PATCH or DELETE is not REST tidiness. It is what makes the other layers apply at all.
Check the cookie itself too
Most of CSRF defence rests on the session cookie's own attributes. A __Host- prefix makes
the cookie host-only in a way the browser enforces, which closes the subdomain hole that defeats
unsigned double-submit. Build and check the cookie with
Secure Cookie Builder, and see what a live site sets with
Cookie Security Checker.
Everything on this page runs in your browser. A framework configuration is not secret, but it routinely names internal hosts and there is no reason for it to travel.
Frequently asked questions
Is SameSite=Lax enough on its own?
No. It handles the common browser case cheaply, and it leaves cross-site top-level GET open, does nothing against a same-site attacker such as a compromised subdomain, and is not enforced identically everywhere. Keep a token as well.
What is wrong with plain double-submit?
It assumes an attacker cannot set cookies on your domain. A compromised or hostile subdomain can, because cookies are shared across subdomains in a way the same-origin policy is not. Sign the token and the weakness goes away.
Does requiring JSON protect me?
Only while nothing else accepts form encoding and your CORS policy does not permit the header. It is an assumption that outlives its conditions. Require a custom header instead - that needs a preflight, which is a real check.
Do I need CSRF protection on a pure API with bearer tokens?
If authentication is a bearer token the browser does not attach automatically, then no - CSRF depends on ambient credentials. If any part of it authenticates with cookies, yes.
Is my configuration uploaded when I paste it?
No. It is pattern-matched in your browser and nothing is transmitted.
References
Related tools
Other Tools
Popular tools from across A2Z
Rate this tool
Was this tool useful? Your feedback helps us improve it.