Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix a CSRF vulnerability by making the server reject every state-changing request that lacks valid evidence it came from your application. Start with your framework’s built-in protection; if you must implement a defense yourself, use a synchronizer token for stateful sessions or a properly session-bound double-submit design for stateless applications. Keep state changes off GET requests, validate request origins, and treat SameSite cookies and Fetch Metadata as additional layers—not substitutes for request validation.

What a CSRF fix must prevent

Cross-site request forgery (CSRF) takes advantage of a browser that automatically sends credentials, such as a session cookie, to a trusted site. An attacker can induce a logged-in user’s browser to send a request the user did not intend. The application must therefore check each state-changing request on the server, rather than assume that a request carrying a valid session cookie is legitimate.

A defense is incomplete if an attacker can omit or alter its required token or other request evidence and the server still performs the action. Apply the check to every endpoint that changes data or account state, including browser forms, JavaScript requests, GraphQL mutations, uploads, administrative actions, and password or email changes.

Find and scope the vulnerable request

  1. Reproduce the reported behavior with an authenticated session. Identify the exact endpoint, method, action, and credentials the browser sends.
  2. Check whether the server accepts the action when the CSRF field or header is missing, changed, or supplied from a different session. Record the response and whether the state actually changed.
  3. Inventory all state-changing routes, including alternate interfaces for the same action. A fix on one form does not protect a separate API endpoint that performs the same operation.
  4. Change any state-changing GET route to POST, PUT, PATCH, or DELETE, as appropriate. GET must be safe to trigger through links, previews, crawlers, and browser navigation; it must not perform the action.

Choose the right request-validation pattern

First check whether your framework or platform already provides CSRF middleware or another maintained protection mechanism. OWASP recommends using available framework protection before building custom token or Fetch Metadata logic. Exact middleware names, defaults, and configuration differ by framework, so follow the documentation for your application’s stack and verify what the deployed configuration actually enforces.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Defense Best fit What it checks Key limitation or trade-off
Framework CSRF protection Applications where the framework provides maintained protection Use the framework’s documented server-side request validation. Names, defaults, and requirements depend on the framework and configuration; confirm coverage for every state-changing route.
Synchronizer token Stateful applications that associate a server-side session with the user A server-generated secret, unpredictable token is associated with the session or request, sent with the action, and compared server-side. Requires server-side validation and careful handling so the token is not exposed.
Double-submit cookie Stateless applications that cannot keep per-session token state on the server The request carries a value that is properly bound to the session context and checked according to maintained implementation guidance. A simple cookie/value comparison is not enough unless the design securely binds the value to the session. Follow framework guidance rather than inventing a scheme.
Origin or Referer validation An additional browser-request check, with a fallback when one header is absent Compare the supplied origin with the application’s exact scheme, host, and port. Headers may be absent in some requests or clients. Do not use this as a reason to accept a mere domain suffix match.
Fetch Metadata An additional signal for browser requests Use headers such as Sec-Fetch-Site to identify cross-site requests and refine policy with related Fetch Metadata headers. Some clients omit the headers, so retain an Origin or Referer fallback and the application’s main request validation.
SameSite session cookie Defense in depth for browser sessions Restricts when browsers send the session cookie in cross-site contexts, depending on the configured SameSite value and request context. It is not a universal replacement for validating state-changing requests.

Implement token validation for forms and APIs

HTML forms and stateful sessions

With a synchronizer-token pattern, generate a unique, secret, unpredictable token on the server and associate it with the user’s session or request. Include it in the form as a hidden field. On submission, compare the supplied value with the expected value on the server and reject the request if it is missing or does not match. Do not let a client choose the expected value.

JavaScript, JSON, and GraphQL requests

For browser JavaScript requests, send the token in a custom request header or in the JSON request body, then validate it server-side. A custom header is generally preferable to putting a token in a URL. A browser’s cross-origin rules normally prevent an untrusted site from setting a custom header without a successful CORS preflight, but that protection depends on your CORS policy: do not allow untrusted origins to send credentialed requests.

Apply the same server-side check to JSON endpoints, GraphQL mutations, uploads, and other non-form requests that change state. A request being JSON, or arriving at an API route, does not by itself establish that it is safe from CSRF when the browser sends ambient credentials.

Stateless session designs

If the application is stateless and cannot retain a server-side synchronizer token, use a double-submit design that binds the submitted value to the session context. Because an unbound cookie-and-request comparison can be unsafe, use maintained framework guidance for the exact construction and validation rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add origin, Fetch Metadata, and cookie defenses

Validate Origin and Referer precisely

For a state-changing request with an Origin header, require an exact match on scheme, host, and port. If Origin is absent, parse Referer and compare its full origin. A check that only accepts a hostname suffix can mistakenly trust a hostile lookalike or subdomain. If both headers are absent, block the request or monitor the case explicitly before deciding whether a compatibility exception is safe.

Use Fetch Metadata as a signal

Treat Sec-Fetch-Site: cross-site on a state-changing request as untrusted. Where useful, use Sec-Fetch-Mode, Sec-Fetch-Dest, and Sec-Fetch-User to refine the policy for expected browser interactions. OWASP’s guidance says all major browsers have supported Fetch Metadata since March 2023 and reports over 98% global coverage on its page crawled in 2026. Because clients can omit these headers, keep strict Origin or Referer validation as a fallback rather than making Fetch Metadata the only check.

Set session-cookie attributes thoughtfully

Configure an appropriate SameSite value for the session cookie, and use Secure and HttpOnly consistently with the session’s threat model. SameSite can reduce cross-site cookie sending, but it does not remove the need for server-side validation. Avoid setting a sensitive cookie across an entire registrable domain when an uncontrolled subdomain or CNAME could share it.

Prevent token leakage and account for XSS

  • Never put a CSRF token in a URL or query string. URLs can be retained in browser history and logs or exposed in Referer headers when a page links to an external site.
  • Do not write token values to application logs. Log the rejection and relevant request context without recording the secret itself.
  • For AJAX requests, prefer a custom header over a URL parameter.
  • Remember that cross-site scripting (XSS) on the trusted origin can read tokens and undermine token, Origin, Referer, and SameSite protections. CSRF controls do not replace XSS prevention.
  • Review client-side code that turns attacker-controlled inputs, such as URL values, into requests. This client-side CSRF path needs input validation and safe request construction of its own.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Verify the fix on every state-changing endpoint

For each route in the inventory, test a legitimate request and confirm it still performs the intended action. Then make each negative test independently and confirm the server rejects the request without changing state:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws
  • Comes with secure packaging
  • It can be a gift item
  • Easy to read text
  • Omit the token.
  • Submit a random or altered token.
  • Submit a token associated with another session.
  • Send a cross-origin Origin or a hostile Referer.
  • Send Sec-Fetch-Site: cross-site.
  • Where the implementation uses per-request tokens, check replay and browser back-button behavior.

Confirm rejection is logged without the token secret, and check alternate interfaces for the same action so one unprotected route does not bypass the fix. The expected rejection status and user-facing behavior depend on the application; the essential result is that an invalid request cannot complete the state change.

Quick Recap

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.