Cross-Site Request Forgery (CSRF): The Complete Practical Guide

Bypassing CSRF Token Validation

How CSRF tokens are defeated: removing or blanking the token, reusing another session's token, method-scoped checks, settable cookies, and weak tokens.

Published

The CSRF token is the main defense, and most CSRF findings are not a missing token but a token that is checked badly. This page is the checklist you run against any tokened request: the handful of validation mistakes that turn a protected action back into a forgeable one. Practice on a free live target.

Step 1: capture the request

Intercept a state-changing request and understand how its token works before attacking it. Note three things: where the token is carried (a hidden form field, a custom header, or a cookie echoed in the body), what it looks like (random per request, random per session, or suspiciously structured), and ideally how the server reacts to a tampered one. That tells you which of the tests below to prioritise.

Step 2: run the bypass checklist

Each item is a distinct server-side mistake. Try them in roughly this order.

Remove the token entirely

Delete the token parameter and replay. If the request still succeeds, the token is generated but never validated, or only validated when present. This is the most common finding.

POST /account/email        (original has: csrf=K7f...&email=...)
POST /account/email        (send just: [email protected])

Send an empty token

Keep the parameter but blank its value. Some validators only run the comparison when the token is non-empty, so an empty value skips the check.

<input type="hidden" name="csrf" value="">

Reuse a token from another account

Mint a valid token in your own session and use it in the victim's. If it is accepted, the token is not bound to the session, which is a full bypass: you embed your own valid token in the payload.

Flip the HTTP method

If the token is enforced on POST, try the same action as a GET, or add a method-override parameter the framework might honour. Method-scoped validation (token checked on POST, ignored on GET) is a classic hole.

POST /account/email  with token   ->  GET /account/email?email=...   (no token required)
or add:  _method=POST

Move the token between body and query string

If the server reads parameters loosely (checking the query string as well as the body, or vice versa), it may validate a token in one place while taking the real values from the other. Supply the token where it is checked and the payload where it is read.

Some apps use the "double submit" pattern: the token is both a cookie and a body field, and the server only checks that the two match, not that either is tied to the session. If you can set that cookie (via a subdomain, a separate injection, or because the app lets you), you set the cookie and the matching body field to the same attacker-chosen value, and they match.

Use a weak or reflected token

If the token is predictable (sequential, a timestamp, a hash of something you know) or is reflected back from a value you supply earlier in the flow, you can generate or capture a valid one yourself.

Step 3: confirm

Replay the modified request and verify the state change actually happens, ideally on a fresh victim session rather than your own, since your own session may accept your own token legitimately. The confirmation is that the action completes without a token the attacker should not be able to supply.

Turning it into a PoC

Once you know which check is broken, wrap the request in an auto-submitting form (or an image tag for a GET) so a logged-in victim who opens your page fires it automatically:

<body onload="document.forms[0].submit()">
  <form action="https://target.example/account/email" method="POST">
    <input type="hidden" name="email" value="[email protected]">
  </form>
</body>

Include or omit the token field to match the exact weakness you found.

Fixing it

  • Validate the token on every state-changing request, and reject the request outright when the token is missing or empty.
  • Bind the token to the user's session so a token from another session is rejected.
  • Enforce it regardless of HTTP method, and never let a method override skip the check.
  • Avoid naive double-submit: if you use it, sign the token and scope the cookie tightly so a subdomain cannot set it.

Full guidance is in preventing CSRF. Next, see how the browser's SameSite default interacts with all this in bypassing SameSite restrictions, or try a token bypass on a free lab.

← Back to Cross-Site Request Forgery (CSRF): The Complete Practical Guide