Cross-Site Request Forgery (CSRF)

Victim’s authenticated browser is tricked into firing a state-changing request. Relies purely on cookies/session being auto-attached by the browser, attacker never sees the response (blind).

Types

Traditional (form-based)

Auto-submitting HTML form on attacker page, POSTs to the target while victim’s cookies ride along.

<form action="https://target/transfer" method="POST" id="f">
  <input type="hidden" name="to" value="attacker">
  <input type="hidden" name="amount" value="1000">
</form>
<script>document.getElementById('f').submit();</script>

No form needed if the vulnerable action accepts GET. A bare <img src> or <a href> is enough, no JS, no click confirmation dialog like a redirect.

<img src="https://target/transfer?to=attacker&amount=1000" width="0" height="0">

Look for state-changing actions still wired to GET, these are the easiest wins and don’t even need a landing page, an email with an image tag works.

XHR/Fetch (async/JSON APIs)

Same trust exploited, just via fetch/XMLHttpRequest instead of a form. Matters because JSON body APIs are often assumed “safe” from CSRF since forms can’t send application/json without triggering a CORS preflight. Bypass: send as text/plain or standard form-urlencoded, most frameworks parse the body regardless of declared content-type.

<script>
fetch('https://target/api/updateEmail', {
  method: 'POST',
  credentials: 'include',
  headers: {'Content-Type': 'text/plain'},
  body: JSON.stringify({email: '[email protected]'})
});
</script>

Also check if the endpoint accepts a form-encoded equivalent of the JSON fields, kills the “it’s JSON so it’s CSRF-safe” assumption instantly.

CORS misconfig CSRF

Access-Control-Allow-Origin: * combined with credentials read back (not just fire-and-forget) lets attacker read the response too, not just trigger the action. Check for reflected Origin header (ACAO: <attacker origin> mirrored back) plus Access-Control-Allow-Credentials: true, that’s a full read/write CSRF, worse than blind.

Flash-based (legacy)

Malicious .swf on attacker’s site abusing crossdomain.xml misconfig (allow-access-from domain="*"). Dead tech since Flash EOL Dec 2020, only relevant on legacy/embedded systems still serving Flash content.

Token implementation weaknesses to check

Presence of a CSRF token doesn’t mean it’s actually protecting anything. Check:

If attacker controls or can inject into attacker.target.com (XSS on a subdomain, forgotten dev subdomain, subdomain takeover), they can set a cookie scoped to domain=target.com that overrides the double-submit cookie for the parent domain, then auto-submit a form with the matching token value. Chain: subdomain compromise + predictable/known token value + double-submit pattern.

Bypass checklist when pentesting

Defence quick reference