What is Cross-Site Request Forgery (CSRF)? Ways to Exploit, Examples and Impact
Understand Cross-Site Request Forgery (CSRF) with technical examples and payloads. Learn how to defend your web applications using modern security practices.
Cross-Site Request Forgery, commonly known as CSRF (pronounced "sea-surf"), is a web security vulnerability that allows an attacker to induce users to perform actions they do not intend to perform. By leveraging the trust a web application has in a user's browser, an attacker can bypass the UI and execute state-changing requests—such as changing passwords, transferring funds, or updating account details—without the user's knowledge. In the modern landscape of cybersecurity, understanding CSRF is essential for both developers and security professionals to ensure that user sessions remain secure and private.
Understanding the Fundamentals of CSRF
At its core, CSRF is often referred to as the "Confused Deputy" attack. In this scenario, the web browser acts as the deputy, and the web server is the authority. The attacker tricks the deputy (the browser) into using its authority (the user's session cookies) to perform an action on the server that the user never authorized.
Unlike Cross-Site Scripting (XSS), which aims to steal data or execute scripts within the context of a page, CSRF focuses exclusively on state changes. The attacker doesn't necessarily see the response of the forged request; their goal is simply to ensure the request reaches the server and is processed as a legitimate action from the authenticated user. Because the browser automatically includes session identifiers like cookies in requests to the associated domain, the server often has no inherent way of distinguishing a legitimate user-initiated click from a malicious script-initiated request.
How CSRF Works: The Technical Mechanics
To understand how a CSRF attack unfolds, we must look at how browsers handle HTTP requests and session management. When you log into a website, the server typically sends back a Set-Cookie header. This cookie contains a unique session ID. For every subsequent request you make to that domain, your browser automatically attaches that cookie in the Cookie header.
The Role of Browser Cookies
Consider a banking application hosted at bank.com. When you log in, bank.com sets a session cookie. If you then open a new tab and visit malicious-site.net, that site can contain a script that sends a request to bank.com/transfer-funds. Because your browser still holds the session cookie for bank.com, it will automatically attach it to the request. The server at bank.com sees a valid session cookie and processes the transfer, assuming you initiated it.
Prerequisites for a Successful CSRF Attack
For a CSRF attack to be feasible, three primary conditions must be met:
- A Relevant Action: There must be an action within the application that the attacker has a reason to induce. This is typically a state-changing action, such as changing a password, deleting a record, or making a purchase.
- Cookie-Based Session Handling: The application must rely solely on HTTP cookies to identify the user who made the request. There should be no other mechanism (like a unique header or token) required to validate the session.
- No Unpredictable Parameters: The requests that perform the action must not contain any parameters whose values the attacker cannot determine or guess. For example, if a request requires a secret token that is unique to the user's session, the attacker cannot forge the request unless they can predict that token.
Types of CSRF Exploits with Examples
CSRF attacks generally fall into two categories based on the HTTP method used by the target application: GET-based and POST-based.
1. GET-based CSRF Attacks
GET requests are the easiest to exploit because they can be triggered by simple HTML tags that fetch resources. If an application uses GET requests for state-changing actions (which is a violation of HTTP best practices), it is highly vulnerable.
Example Scenario:
A vulnerable application allows users to change their email address via a GET request:
GET /user/update-email?email=newemail@example.com HTTP/1.1
Host: vulnerable-site.com
Cookie: session=abc123xyz
An attacker can exploit this by embedding a hidden image on a malicious page:
<img src="https://vulnerable-site.com/user/update-email?email=attacker@evil.com" width="0" height="0" />
When the victim visits the attacker's page, the browser attempts to load the "image," effectively sending the email-change request to vulnerable-site.com with the victim's session cookie.
2. POST-based CSRF Attacks
Most modern applications use POST requests for sensitive actions. While these cannot be triggered by an <img> tag, they can be easily forged using an HTML form and a small amount of JavaScript to auto-submit that form.
Example Scenario:
A bank uses a POST request to transfer money:
POST /transfer HTTP/1.1
Host: bank.com
Content-Type: application/x-www-form-urlencoded
Cookie: session=user-session-id
amount=1000&toAccount=attacker-id
The attacker creates a malicious webpage with a hidden form:
<html>
<body onload="document.forms[0].submit()">
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="amount" value="1000" />
<input type="hidden" name="toAccount" value="attacker-id" />
</form>
</body>
</html>
When the victim visits this page, the script automatically submits the form. The browser sends the POST request to bank.com, including the victim’s cookies, and the transfer is executed.
CSRF vs. XSS: What is the Difference?
It is common to confuse CSRF with Cross-Site Scripting (XSS), but they are fundamentally different.
- XSS is about executing malicious scripts in the victim's browser to steal data (like cookies or local storage) or perform actions on the user's behalf by interacting with the page's DOM. In XSS, the attacker gains full control over what the user sees and does on that specific site.
- CSRF is about tricking the browser into sending a request to a different site where the user is already authenticated. The attacker does not need to execute code on the target site; they just need to trigger a request from the victim's browser to the target site.
In short: XSS exploits the trust a user has for a website, while CSRF exploits the trust a website has in a user's browser.
Bypassing Common (and Weak) CSRF Defenses
Many developers attempt to implement custom defenses that are often easily bypassed by experienced attackers.
Bypassing Referer Header Checks
Some applications check the Referer or Origin header to ensure the request originated from their own domain. However, this can be bypassed in several ways:
- Stripping the Referer: Attackers can use a
<meta name="referrer" content="no-referrer">tag to prevent the browser from sending the Referer header. If the server is configured to allow requests when the header is missing, the defense fails. - Domain Spoofing: If the server only checks if the Referer contains the domain name, an attacker could host the exploit on
vulnerable-site.com.attacker.com.
Bypassing Weak Token Implementations
If an application uses CSRF tokens but doesn't validate them correctly, it remains vulnerable. Common mistakes include:
- Tokens not tied to user sessions: The server checks if a token is valid but doesn't check whose token it is. An attacker can use their own valid token in an exploit against another user.
- Skipping validation on certain methods: The server validates tokens on POST requests but forgets to check them on PUT or DELETE requests.
The Impact of CSRF Vulnerabilities
The impact of a CSRF attack depends entirely on the functionality of the target application and the privileges of the victim user.
- Account Takeover: By forging a request to change the user's email or password, an attacker can gain full control of the account.
- Financial Loss: In banking or e-commerce apps, CSRF can be used to transfer funds or make unauthorized purchases.
- Data Manipulation: Attackers can delete records, change privacy settings, or post content on behalf of the user, leading to reputational damage.
- Administrative Compromise: If the victim is an administrator, the attacker could forge requests to create new admin users, change site-wide configurations, or shut down services.
Modern Defenses: How to Prevent CSRF
Preventing CSRF requires a multi-layered approach. Relying on a single defense is rarely sufficient.
Anti-CSRF Tokens (Synchronizer Token Pattern)
This is the most effective defense. The server generates a unique, cryptographically strong, and unpredictable token for the user's session. This token must be included in every state-changing request (usually as a hidden field in forms or a custom HTTP header).
When the request reaches the server, it compares the token in the request with the token stored in the user's session. If they don't match or the token is missing, the request is rejected. Since an attacker cannot read the token (due to the Same-Origin Policy), they cannot forge a valid request.
The SameSite Cookie Attribute
SameSite is a cookie attribute that tells the browser whether to send cookies with cross-site requests. It has three values:
- Strict: Cookies are only sent for first-party requests (the site currently in the URL bar).
- Lax: Cookies are not sent on cross-site subrequests (like images or frames) but are sent when a user navigates to the origin site (e.g., following a link).
- None: Cookies are sent in all contexts. This requires the
Secureflag.
Modern browsers (like Chrome) now default to SameSite=Lax, which provides significant protection against many CSRF scenarios but is not a complete solution on its own.
Double Submit Cookie Pattern
In this pattern, a random value is sent both in a cookie and as a request parameter. The server verifies that the values match. This is useful for stateless applications (like APIs) where the server doesn't store session state. However, it can be bypassed if an attacker can perform a "Cookie Toss" (setting a cookie for a subdomain).
Custom Request Headers
For AJAX-heavy applications, adding a custom header (e.g., X-Requested-With) is an effective defense. Because browsers restrict the addition of custom headers to cross-domain requests unless permitted by CORS, an attacker cannot easily forge a request that includes this header.
Conclusion
Cross-Site Request Forgery remains a critical threat because it exploits the very mechanism that makes the modern web convenient: persistent sessions. While browser-level defenses like SameSite have reduced the prevalence of simple CSRF exploits, developers must remain vigilant. Implementing robust Anti-CSRF tokens and ensuring that state-changing actions are never handled via GET requests are fundamental steps in securing a web application.
To proactively monitor your organization's external attack surface and catch exposures before attackers do, try Jsmon. By identifying your assets and their security posture, Jsmon helps you stay ahead of vulnerabilities like CSRF and beyond.