Cross-Site Request Forgery (CSRF)
Cross-Site Request Forgery forces authenticated users to execute unintended actions on web applications by exploiting the browser's automatic inclusion of credentials in cross-origin requests.
Technical Description
Cross-Site Request Forgery (CSRF) is an attack that forces an authenticated user’s browser to send a forged HTTP request, including the user’s session cookie and any other automatically included authentication information, to a vulnerable web application. The application cannot distinguish the forged request from a legitimate one because the browser automatically attaches credentials for the target domain.
The attack works because browsers automatically include cookies (including session cookies) with every request to a domain, regardless of the origin of the request. If a user is logged into bank.com and visits a malicious page, that page can trigger requests to bank.com that carry the user’s authenticated session.
A classic CSRF attack:
<!-- Malicious page hosted on attacker.com -->
<!-- Auto-submitting form that transfers money -->
<form action="https://bank.com/transfer" method="POST" id="csrf-form">
<input type="hidden" name="to" value="attacker-account" />
<input type="hidden" name="amount" value="10000" />
</form>
<script>document.getElementById('csrf-form').submit();</script>
When the victim visits this page while logged into bank.com, the browser submits the form with the victim’s session cookie, and the transfer executes as if the victim initiated it.
CSRF can be delivered through multiple vectors:
- HTML Forms: Auto-submitting forms for POST requests. Forms can be hidden in zero-sized iframes.
- Image Tags / GET Requests:
<img src="https://target.com/api/delete?id=123">triggers GET-based state changes. - XMLHttpRequest / Fetch: For APIs that accept JSON, though CORS restrictions often prevent reading the response (the request itself still executes for simple requests).
- Clickjacking Combinations: Layering CSRF with UI redressing to trick users into clicking submit buttons on invisible, overlaid forms.
Modern defenses have reduced CSRF prevalence, but it remains relevant in applications that do not implement SameSite cookies, rely solely on cookies for authentication, or have misconfigured CORS policies.
Real-World Impact
CSRF has been exploited in numerous high-profile attacks:
- Netflix (2006): CSRF allowed attackers to change account settings including the shipping address, effectively hijacking DVD deliveries and account control.
- Gmail (2007): A CSRF vulnerability allowed attackers to add email forwarding filters to a victim’s Gmail account, silently forwarding all email to the attacker.
- Router Attacks (Ongoing): CSRF against home router admin panels (which often lack CSRF tokens) allows attackers to change DNS settings, redirect all traffic through malicious resolvers, and intercept credentials for every site the victim visits.
While CSRF does not directly steal data, it enables attackers to perform any action the victim can perform: changing passwords, modifying account settings, making purchases, transferring funds, and granting third-party application access.
Detection Methodology
CSRF testing involves verifying that state-changing operations cannot be forged:
- Token Presence Check: Verify that all state-changing endpoints (POST, PUT, DELETE) require a CSRF token. Inspect forms for hidden token fields and API calls for CSRF headers.
- Token Validation Testing: Submit requests without the CSRF token, with an empty token, with a token from a different session, and with a modified token. If any succeed, the protection is ineffective.
- SameSite Cookie Analysis: Check whether session cookies have the
SameSiteattribute set.SameSite=Strictprevents CSRF entirely;SameSite=Laxprevents it for non-GET requests (which is the browser default for cookies without an explicit SameSite value in modern browsers). - CORS Configuration Review: Examine
Access-Control-Allow-Originheaders for overly permissive configurations (*or reflection of the Origin header) that enable cross-origin requests. - GET-Based State Changes: Identify any GET requests that modify data. These are inherently vulnerable to CSRF through image tags and link prefetching even with SameSite=Lax.
How Revaizor Discovers This
Revaizor’s AI agents systematically evaluate CSRF protections across the entire application:
- Comprehensive State-Change Mapping: Revaizor identifies every endpoint that modifies state: form submissions, API calls, AJAX requests, and single-click actions. It builds a complete map of operations that require CSRF protection.
- Token Validation Analysis: For each protected endpoint, Revaizor tests the robustness of the CSRF defense by submitting requests without tokens, with manipulated tokens, with tokens from other sessions, and with expired tokens. It verifies that the protection cannot be bypassed.
- Cookie Attribute Auditing: Revaizor analyzes all cookies set by the application, evaluating SameSite attributes, Secure flags, and domain scope to identify cookies that are vulnerable to cross-origin inclusion.
- Proof-of-Concept Generation: When CSRF is confirmed, Revaizor generates a working proof-of-concept HTML page that demonstrates the attack, making it immediately clear to developers how the vulnerability can be exploited and why it matters.
Remediation
Modern CSRF defense relies on multiple complementary mechanisms:
# Flask - using CSRF tokens with WTForms
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
# In templates:
# <form method="POST">
# <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
# ...
# </form>
# For AJAX APIs, include the token in a custom header:
# X-CSRF-Token: <token_value>
// Express.js - using csurf middleware
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.get('/form', csrfProtection, (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
app.post('/process', csrfProtection, (req, res) => {
// CSRF token automatically validated
res.send('Action completed');
});
Comprehensive CSRF prevention:
- SameSite Cookies: Set
SameSite=Strict(orLaxas a minimum) on all session and authentication cookies. This is the most effective single defense and is now the default behavior in modern browsers. - Synchronizer Token Pattern: Include a unique, per-session or per-request CSRF token in all state-changing forms and API requests. Validate the token server-side before processing the request.
- Double Submit Cookie: Set a random value in both a cookie and a request parameter. The server verifies both values match. This approach does not require server-side state.
- Custom Request Headers: For API-based applications, require a custom header (e.g.,
X-Requested-With) that cannot be set by cross-origin forms. Verify its presence server-side. - No GET-Based State Changes: Ensure all state-modifying operations use POST, PUT, PATCH, or DELETE methods. GET requests should never create, update, or delete data.
- CORS Restriction: Configure CORS to only allow requests from trusted origins. Never reflect the Origin header or use
Access-Control-Allow-Origin: *for authenticated endpoints.
Related Glossary Terms
Related Comparisons
AI Pentesting vs Bug Bounty Programs
AI pentesting and bug bounty programs both find vulnerabilities, but they differ in predictability, coverage, cost structure, and the type of findings they surface.
Autonomous Pentesting vs PTaaS Marketplaces
Comparing AI-driven autonomous pentesting with PTaaS marketplace platforms like Cobalt and Synack to clarify where each delivery model creates the most value.
Continuous vs Annual Pentesting
Annual pentesting was designed for a world where software shipped quarterly. Continuous pentesting was designed for a world where software ships daily. Here is how to evaluate which model fits.
Related Articles
From Quarterly Pentests to Continuous Security Validation
Annual or quarterly pentests made sense when releases were rare. Modern teams deploy daily. Your security testing needs to match.
Mission-Driven Security Testing: A New Paradigm
Why defining clear objectives before testing leads to better security outcomes than running generic scans.