Glossary
Web application security

What is Cross-Site Request Forgery?

Also calledCSRFXSRFSession riding

Definition

Cross-site request forgery is a vulnerability in which a site an attacker controls causes a victim browser to send a state-changing request to a different site where the victim is already authenticated, using credentials the browser attaches automatically.

What cross-site request forgery is

A browser attaches cookies to a request based on where the request is going, not on where it came from. That single behaviour is the whole vulnerability. If an application decides that a valid session cookie is sufficient authorisation for a state-changing action, then any page anywhere on the internet can trigger that action on behalf of anyone who is logged in, because the browser will attach the cookie without being asked.

The attacker never sees the response. This is not an information disclosure class. It is a class about causing an effect: change an email address, transfer a balance, add an API key, promote an account. Anything that reads rather than writes is out of scope for CSRF, which is why the first triage question is always whether the endpoint changes state.

What SameSite changed, and what it did not

Browsers now default cookies to SameSite=Lax when the attribute is absent, which blocks the classic case: a cross-site form POST no longer carries the session cookie. That has made naive CSRF much rarer, and it has also made a generation of testers assume the class is dead. It is not, and the gaps are specific.

  • Lax still permits top-level cross-site GET navigation to carry the cookie. An application that changes state on a GET is still exposed.
  • A same-site attacker is unaffected. A subdomain the attacker can write to is same-site for cookie purposes, so an XSS or a takeover on any subdomain restores the full class.
  • Cookies explicitly set to SameSite=None, which is required for legitimate cross-site embedding, opt back out of the protection entirely.
  • Authorization headers and bearer tokens are not cookies. An API that authenticates with a header is not CSRF-exposed in the first place, which is a design answer rather than a mitigation.

What actually fixes it

Bind the request to something the attacker cannot read. A synchroniser token stored server-side against the session and echoed in the request body is the durable answer, because it requires the requesting page to have read a value the same-origin policy prevents a cross-site page from reading. The double-submit variant, where the token is both a cookie and a body field, is cheaper and weaker: it fails against an attacker who can set cookies on the domain, which any subdomain can do.

Worked example

What it looks like in practice

csrf-proof-of-concept.html
<!-- A proof of concept for a state-changing POST with no token.
     Host it on a domain you control and open it while logged in to the
     target in the same browser. It should be run only against a system
     you have written permission to test. -->
<html>
  <body onload="document.forms[0].submit()">
    <form action="https://app.example.com/settings/email" method="POST">
      <input type="hidden" name="email" value="[email protected]" />
    </form>
    <p>If the address changed, the endpoint accepted a cross-site request.</p>
  </body>
</html>
The minimal demonstration. The point is the absence of anything clever: if this works, the endpoint is relying on the cookie alone.
Commonly confused with

What it is not

The distinction matters more than the definition does, because these are the terms people swap by accident in a report.

Flashcards

4 cards

Tap a card to reveal the answer. Answers are in the page source, so this works with JavaScript disabled.

  • What browser behaviour makes CSRF possible?

    Cookies are attached based on the destination of a request, not on the origin of the page that caused it, so a cross-site page can trigger an authenticated request.

  • Why is a read-only endpoint not a CSRF finding?

    The attacker never sees the response. CSRF causes an effect rather than disclosing data, so an endpoint that does not change state has nothing to abuse.

  • Name two situations where SameSite=Lax does not protect you.

    State-changing GET requests, which Lax still permits on top-level navigation, and a same-site attacker such as a compromised or attacker-writable subdomain.

  • Why is the double-submit cookie pattern weaker than a synchroniser token?

    It only proves the requester could set a cookie, and any subdomain can set cookies on the parent domain. A synchroniser token proves the requester could read a same-origin response.

Instructor note

Where people get this wrong

Two mistakes, both common. The first is reporting a missing CSRF token on a login form or a search box and being surprised when it is closed: with no state change there is no finding, and the exceptions such as login CSRF need their own impact argument. The second is assuming SameSite=Lax closed the class. It did not, and the subdomain case in particular turns a medium-severity XSS on a forgotten marketing host into a full account takeover on the main application. Always check what else lives on the registrable domain.
Cyber VK Security Curriculum, Pre-publication content owner
Practise it

Where you can use this

The G1 gate for this template: the artifacts below exist nowhere else in this combination.

Cyber VK Security Curriculum

Pre-publication content owner

Internal ownership label for the web-security curriculum.

Technically reviewed by Cyber VK Lab Engineering

Updated

All glossary terms

What Is Cross-Site Request Forgery? Definition and Example