SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration
SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration

All Entries

CategoryCross-Site Request Forgery
Typical SeverityHigh
OWASPA01:2021 – Broken Access Control
CWECWE-352: Cross-Site Request Forgery (CSRF)
Also known asXSRF, Sea Surf, Session Riding, One-Click Attack, Hostile Linking
Affected systemsWeb applications using cookie-based or HTTP Basic/Digest authentication that perform state-changing operations via GET or POST
Relevant standardsRFC 6265 (HTTP Cookies), OWASP CSRF Prevention Cheat Sheet

Overview

Cross-Site Request Forgery (CSRF) is a client-side vulnerability in which an attacker induces a victim's browser to issue an HTTP request — carrying the victim's cookies or HTTP authentication credentials — to a target application without the victim's knowledge or intent. Because the browser automatically attaches stored credentials, the target application cannot distinguish the forged request from a legitimate one based on credentials alone.

CSRF was listed in the OWASP Top 10 as a standalone category for many years and is now codified under CWE-352. It is particularly dangerous for operations that modify state: changing a password or email address, initiating a funds transfer, altering account privileges, or deleting records.

How it works

The attack relies on two properties of web browsers: cookies are automatically sent with every request to the cookie's origin, and the Same-Origin Policy governs JavaScript read access to responses but does not block the browser from sending cross-origin requests.

  1. Authentication: The victim logs into a target application (e.g., a banking site) and receives a session cookie stored in the browser.
  2. Lure: While the session is still active, the victim visits or is tricked into loading a malicious page (crafted email, third-party website, or injected ad).
  3. Forged request: The malicious page contains markup or script — an <img> tag with a crafted src, a hidden HTML form with JavaScript auto-submit, or a fetch() call with appropriate CORS pre-flight bypass — that causes the browser to issue a request to the target application.
  4. Credential attachment: The browser automatically appends the session cookie (and any HTTP Basic/Digest credentials) to the outbound request.
  5. Action execution: The target application, seeing valid credentials, processes the request as if it were intentional.

Key technical factors that affect exploitability:

  • HTTP method: GET-based state changes are trivially exploitable via <img src> or <link href>. POST-based actions require a form or fetch, but are still exploitable with simple HTML.
  • Content-Type restrictions: application/json POST requests normally trigger a CORS preflight, which the browser will block for cross-origin requests to non-permissive endpoints — but text/plain or multipart/form-data do not trigger preflights and can still carry JSON-like payloads.
  • Cookie attributes: Absence of the SameSite attribute (or using SameSite=None) means cookies are sent on all cross-site requests, widening attack surface.
  • Subdomain trust: If subdomains share cookies (broad Domain attribute), a compromised subdomain can serve a CSRF payload against the main application.

Business impact

A successful CSRF attack executes arbitrary state-changing operations with the victim's full privileges. Concrete consequences include:

  • Account takeover: An attacker changes the victim's email address or password, locking them out and gaining full control.
  • Financial fraud: Unauthorized fund transfers, purchases, or subscription changes in payment-enabled applications.
  • Data destruction or exfiltration setup: Deleting records, changing data-sharing settings, or adding an attacker-controlled administrator account.
  • Privilege escalation: Granting the attacker elevated roles within the application.
  • Regulatory and legal exposure: Unauthorized processing of personal or financial data may trigger obligations under GDPR, PCI DSS, or other frameworks.
  • Reputational damage: Users who experience unexplained account changes lose trust in the platform.

How to fix it

  1. Synchronizer Token Pattern (primary defense): Generate a cryptographically random, per-session (or per-request) token and embed it as a hidden field in every state-changing HTML form or as a custom HTTP header (X-CSRF-Token) for AJAX. Validate the token server-side on every mutating request. Tokens must be unguessable (at least 128 bits of entropy) and tied to the session.
  2. Double Submit Cookie: Set a random value in both a cookie and a request parameter (or header). Validate that they match server-side. This is weaker than the synchronizer pattern if subdomain cookie injection is possible but is useful for stateless architectures.
  3. SameSite Cookie Attribute: Set SameSite=Strict or SameSite=Lax on session cookies. Strict blocks the cookie on all cross-site requests. Lax (the browser default since 2020 in most browsers) blocks it on cross-site sub-resource and form POST requests while allowing top-level navigations. Neither attribute alone is a complete defense — use it as a defence-in-depth layer.
  4. Verify the Origin or Referer header: On the server, check that the Origin header (preferred) or Referer header matches the expected origin. Reject requests that originate from unexpected sources. Be careful with header stripping by proxies and missing headers on direct navigation.
  5. Use custom request headers for AJAX: Require a custom header (e.g., X-Requested-With: XMLHttpRequest) for all AJAX-based state changes. Cross-origin requests cannot set arbitrary headers without a CORS preflight, which the server can reject.
  6. Eliminate GET-based state changes: Ensure that HTTP GET requests are idempotent and never modify server state. Use POST, PUT, PATCH, or DELETE for all mutations, following REST semantics.
  7. Require re-authentication for sensitive operations: For high-impact actions (password change, payment, privilege grant), prompt users to re-enter their password or complete a second factor, independent of CSRF tokens.
  8. Apply CORS policy correctly: A restrictive CORS policy prevents cross-origin JavaScript from reading responses, but it does not prevent simple cross-origin requests from being sent. Do not rely on CORS as a CSRF defense.
  9. Framework defaults: Use the built-in CSRF protection provided by your web framework (Django's CsrfViewMiddleware, Laravel's VerifyCsrfToken, Spring Security's CsrfFilter, Rails' protect_from_forgery, etc.) rather than implementing custom token logic.

References

Frequently asked questions

XSS (Cross-Site Scripting) injects malicious scripts into a page served by the trusted site, allowing the attacker to read data, steal cookies, or perform actions as the victim from within the target origin. CSRF exploits the browser's automatic credential attachment to forge requests from a different origin — without needing to inject or execute code on the target site. XSS is generally considered more severe because it bypasses the Same-Origin Policy entirely. Notably, an XSS vulnerability in the target application also defeats CSRF protections, since the attacker's script can read and replay CSRF tokens.

No. HTTPS encrypts the transport channel and authenticates the server's identity, but it does not prevent the browser from automatically sending cookies on cross-origin requests. CSRF operates at the application layer, above the transport layer, so TLS provides no protection against forged requests.

SameSite=Strict or SameSite=Lax significantly reduces CSRF risk and is a strong defence-in-depth control, but it should not be the only protection. Browser support inconsistencies, legacy browsers, and edge-cases (e.g., top-level navigational GET requests are allowed under Lax) mean that a synchronizer token or origin-verification approach should be used alongside SameSite.

Classical CSRF only forges requests; it does not directly allow the attacker to read the response (the browser enforces the Same-Origin Policy for script-accessible responses). However, a CSRF attack can change data, account settings, or security controls that indirectly expose data — for example, changing the account's email address to one the attacker controls and then triggering a password reset.

REST APIs that accept JSON bodies via Content-Type: application/json are generally safer because cross-origin form submissions cannot set that content type without triggering a CORS preflight. However, if the API also accepts text/plain or multipart/form-data, or if the CORS policy is overly permissive, CSRF is still possible. APIs authenticated solely by cookies (e.g., session cookies set by a login endpoint) require CSRF protection regardless of data format. APIs authenticated by tokens in the Authorization header (Bearer tokens stored in memory, not cookies) are not susceptible to classical CSRF.

Sensagraph automatically inspects web application forms and state-changing endpoints for the presence and validity of CSRF tokens, checks SameSite cookie attributes, and identifies GET requests that perform mutating operations.