What Is Cross-Site Request Forgery (CSRF)? Examples, Vulnerabilities, and Prevention
Cross-site request forgery (CSRF), also known as XSRF or session riding, is an attack approach where threat actors trick trusted users of an application into performing unintended actions.
Cross-site request forgery (CSRF), also known as XSRF or session riding, is an attack approach where threat actors trick trusted users of an application into performing unintended actions.
CSRF attacks exploit the trust that web applications have in authenticated users. This trust makes the apps automatically accept HTTP verbs (POST, GET, PUT, and DELETE) sent from the users’ browsers, and CSRF attacks then go unchecked because apps are unable to distinguish requests generated by legitimate users from requests originating from hackers who are forcing legitimate users to perform unwanted actions.
Say the victim is a regular user trying to make a purchase on an e-commerce website. A CSRF attacker can force them to purchase a different product unknowingly. CSRF attacks can also make users perform critical state-changing actions like transferring funds or changing their credit card pins, login credentials, or email addresses.
If the victim is an admin account, especially one with privileged access, a CSRF attacker can take over the entire app and perform unauthorized actions. So how can a CSRF attack force victims to do all this unknowingly? Let’s take a look.
Understanding how CSRF attacks work
CSRF attacks work by exploiting two channels:
“Trusted” requests: As previously mentioned, a vulnerability in web apps can make apps manage sessions using IDs known to the browser (e.g., session IDs) and nothing more.
Same-origin policy and cross-origin resource sharing loopholes: The same-origin policy (SOP) stops a website—“https://example.com,” let’s say—from communicating with another website, like “https://new-example.com,” which is from a different origin. This protects legitimate websites from rogue websites and the malicious actions they perform—e.g., accessing sensitive web input.
Also aimed at protecting sensitive data and communication, cross-origin resource sharing (CORS) applies a slightly different approach. CORS allows a website, like “https://example.com,” to communicate with another from a different origin (such as “https://new-example.com”), but only if proper access permissions are placed in the HTTP headers.
Despite these restrictions, CSRF attacks bypass SOP and CORS because the malicious HTTP request is coming from the user’s browser, rather than a third-party site.
Here’s how CSRF works step-by-step:
Step 1: The CSRF attacker builds an exploit script or URL.
Step 2: The attacker tricks users into clicking the link or executing the script via social engineering.
Step 3: A user who is already logged in sends the malicious request, the effect of which is only detected after the attack is successful.
Examples
Bank transfer
A CSRF attacker crafts an HTTP request that instantly initiates a funds transfer of $3,000 to the attacker’s account once clicked: GET https://examplebank.com/onlinebanking/transfer?account=hacker&amount=$3000
They disguise the GET request in an innocuous-seeming hyperlink: https://secure-login.example.bank.com/verify?user=you
They embed the disguised link in an email purportedly from your bank and send it to you.
You receive an email titled “Urgent Action Required” while you’re logged into your bank app and immediately click on the link to see what’s going on.
Your browser goes to the session-handling cookie jar to verify that the request is indeed coming from you, an authenticated user. Once verified, the bank app processes the HTTP request and completes the transfer.
ETL pipeline
You’re an ETL pipeline admin. Your pipeline has a web-based management interface that’s vulnerable to CSRF attacks. While you’re logged into the pipeline, you visit a webpage for research. You find a link on that page that reads “ETL Pipeline Optimization Steps.” Curious, you click on it. Unfortunately, the link contains a CSRF script designed to change the configurations of your pipelines, allowing the attacker access for future attacks.
Other types of attacks
Not all CSRF attacks work the same way as the examples above. Some, like login CSRF attacks, trick victims into logging into attacker-owned websites to collect users’ login credentials for future attacks. Some CSRF attacks are also self-loading, typically including one-liner JavaScript code that’s automatically triggered once a user opens the target website. For example:
<script>document.forms[0].submit();
</script>
CSRF vulnerabilities
Of all actions carried out on apps and websites, state-changing actions (like transferring funds or modifying system configurations) are the most vulnerable to CSRF attacks. This is because non-state changing actions that require two-way communication—like requesting a webpage—cannot be leveraged for an attack because the data will be sent to the user and the attacker will have no access to it.
On the other hand, for CSRF attacks to be successful, attackers simply need to craft a malicious request using the right HTTP method—POST, GET, etc. They then exploit a flaw that most apps have, according to OWASP: the tendency to accept authenticated user requests without verifying that the request is unique to the session in which it was sent.
Common CSRF vulnerabilities are either caused by the absence of or flaws in CSRF token implementation. To see if your app is vulnerable to CSRF attacks, check for the following:
The use of session IDs (and nothing more) for session management: This makes apps vulnerable to CSRF since a session ID is stored in the browser cookies and sent alongside both legitimate and CSRF requests.
Token pool vulnerabilities: Associating a pool of CSRF tokens with a system, rather than a user session, allows a threat actor to carry out an attack if they are able to obtain any of the tokens.
Skipped token verification: Some apps are configured to verify tokens when they are present and skip verification when they are absent. In such apps, attackers simply exclude CSRF tokens when crafting HTTP requests.
Token information copied to cookies: Similar to using session IDs stored in cookies, this lets a CSRF attacker exploit the token parameters saved in the cookies.
To detect CSRF vulnerabilities, developers and security teams can:
Use security testing tools to check if the app’s session management depends solely on client-side information, particularly sessions stored in the browser cookie. If it does, the app is vulnerable to client-side CSRF attacks.
Scan for unprotected Ajax and API endpoints, e.g., Ajax requests in which custom headers and anti-CSRF tokens are omitted or API endpoints that process state-changing requests without requiring CSRF tokens.
Focus on state-changing requests bymanually scanning the page rendering to see if CSRF tokens and other CSRF-proof identifiers are included in the links rendered by the app.
Use code scanners to uncover and resolve CSRF vulnerabilities in code.
Common misconceptions about CSRF
OWASP outlines a number of flawed “prevention measures” that are simply ineffectual for CSRF prevention, including:
Using HTTPS alone: Though HTTPS enhances web security, it does not protect against CSRF attacks.
Using a secret cookie: Since cookies, no matter how secret, get submitted with HTTP requests, they cannot verify if a user is being forced to submit a request or not.
Configuring apps to accept POST requests only: While this prevents the attacker from executing CSRF using malicious links, they can still use forged POST requests like the one below:
Cross-site request forgery (CSRF) and cross-site scripting (XSS) are both common web vulnerabilities, but they operate differently and target distinct aspects of web application security. Here's a high-level comparison:
Attributes
CSRF
XSS
Attack vector
Trusted request
Improperly sanitized user input fields
Common targets
Bank, e-commerce, and email apps
E-commerce, healthcare, and bank apps
Vulnerability exploited
An app’s trust in authenticated users’ requests
A users’ trust in the security of input fields in app they use
Goal
To trigger state-changing actions
To steal data or hijack sessions; injection of malicious scripts into webpages viewed by other users.
The success of CSRF attacks depend on the victim performing a state-changing action, the target app using cookie-based session handling, and the app having no unpredictable parameters like CSRF tokens included in HTTP requests.
To thwart CSRF attacks, make sure your applications don’t meet these conditions. Instead, follow the CSRF prevention frameworks and best practices in OWASP’s CSRF prevention cheat sheet. Here are some of OWASP’s top tips to get you started:
Leverage built-in CSRF protection found in frameworks like .NET.
Use server-side verification mechanisms like anti-CSRF tokens to verify every session involving state-changing requests and forms. This creates a session identifier the attacker is unaware of. Furthermore, make tokens secret and unpredictable. This ensures that should a CSRF attacker try to guess it, a token mismatch occurs, alerting the app and the user of an attempted attack.
In stateful software, deploy synchronizer token patterns—where CSRF tokens are generated and stored by the server to verify the legitimacy of user requests. In stateless software, utilize signed double-submit cookies—where the server generates and encrypts a token known to it only and doesn’t store the token but instead sends it to the browser as a cookie on a per-session basis.
Use advanced WAFs to detect and filter out state-changing requests that lack proper CSRF tokens. However, this is not to be used as a sole prevention mechanism because WAFs don’t validate the tokens in the requests; therefore, an incorrect token may still go unnoticed.
Deploy Referer-based validation, where the server confirms that the Referer header in an HTTP request matches the expected domain before processing the request. Still, as CSRF attackers can spoof Referer headers, this tactic isn’t foolproof against CSRF attacks.
Implement defense-in-depth. CSRF tokens are not invulnerable, so the following DiD mechanisms may be necessary:
Use SameSite cookies as your session-handling cookies. Configure the SameSite cookie attribute to strict ( SameSite=Strict). This will prevent the browser from sending session cookies with cross-origin requests, safeguarding against CSRF attacks. Remember, setting the SameSite cookie attribute to lax or none, while necessary at times, won’t fully deter CSRF attacks.
Use custom HTTP headers to prevent a situation where an attacker somehow guesses or captures CSRF tokens. Custom headers are especially useful for safeguarding API and Ajax endpoints.
Consider user interaction–based CSRF defense mechanisms like one-time tokens and re-authentication for every request. (Keep in mind that not all UIB CSRF measures work—for example, CAPTCHA.)
Avoid using GET for state-changing requests, or ensure comprehensive CSRF protection if you must.
Adopt shift-left security:
Embed CSRF protection into the software development lifecycle by integrating frameworks such as Django CSRF protection or Laravel CSRF protection. Both frameworks offer built-in CSRF protection by automatically generating and verifying CSRF tokens in incoming state-changing requests.
Review code for CSRF vulnerabilities before it is shipped.
Protect login forms from login CSRF attacks. An often overlooked CSRF prevention measure, enable login CSRF prevention by including pre-session (sessions before user authentication) CSRF tokens in login forms.
As modern applications continue to evolve, CSRF vulnerabilities have become even more concerning.
In single-page applications (SPAs) for instance, there are three main architectural complexities that make CSRF protection difficult: reliance on persistent sessions, APIs, and client-side state management. This means that protection mechanisms for server-side session management—like anti-CSRF tokens—may fall short because attackers have a longer attack window since user sessions in SPAs persist for longer.
Microservices architecture can also pose problems for CSRF protection. Microservices are common targets for CSRF attacks because of the inherent trust between the different services. The complexity of managing authenticated sessions between so many microservices adds to this challenge.
To prevent CSRF attacks in modern apps, apply per-request, rather than per-session CSRF tokens where possible. Use OAuth 2.0, JWT, or other token-based (rather than cookie-based) authentication. Also, use custom headers that cross-site attackers cannot modify, and ensure proper token management to prevent attackers from accessing CSRF tokens.
Wiz’s approach to CSRF protection
Wiz seamlessly integrates with your code repos and CI pipelines, and Wiz Code continuously scans your code for common code vulnerabilities. Once detected, Wiz Code traces the vulnerabilities to the problem line of code and offers actionable recommendations for immediate remediation.
Wiz also integrates with Appsec tools, like Checkmarx, to offer you unparalleled SAST and runtime CSRF vulnerability detection. These integrations are a powerful solution for enforcing secure coding practices—such as session and token management—to prevent CSRF and other web app vulnerabilities. With its CSRF vulnerability-to-code context, our industry-leading platform empowers you to conduct faster root cause analysis and remediation. Request a demo today to see Wiz in action.
Don't let malicious code compromise your cloud
Learn why CISOs at the fastest growing companies trust Wiz to protect their cloud environments.
Data sprawl refers to the dramatic proliferation of enterprise data across IT environments, which can lead to management challenges and security risks.
Application detection and response (ADR) is an approach to application security that centers on identifying and mitigating threats at the application layer.
Secure coding is the practice of developing software that is resistant to security vulnerabilities by applying security best practices, techniques, and tools early in development.
Secure SDLC (SSDLC) is a framework for enhancing software security by integrating security designs, tools, and processes across the entire development lifecycle.
DAST, or dynamic application security testing, is a testing approach that involves testing an application for different runtime vulnerabilities that come up only when the application is fully functional.