Definition and Overview

Cross-Site Request Forgery (CSRF, also written as XSRF) is a class of web application vulnerability in which an attacker causes a victim's browser to send a forged HTTP request -- including the victim's session cookie and other authentication credentials -- to a vulnerable web application. Because the browser automatically includes session cookies with every request to a domain, the target application cannot distinguish between a legitimate request initiated by the user and a forged request crafted by the attacker.

CSRF attacks exploit the trust that a web application has in the user's browser. Unlike Cross-Site Scripting (XSS), which exploits the trust a user has in a website, CSRF exploits the trust a website has in the user's browser. The attack does not require the attacker to read the response -- it only needs the browser to send the request. This makes CSRF particularly dangerous for state-changing operations such as transferring funds, changing passwords, modifying account settings, or deleting resources.

The vulnerability has been consistently ranked in the OWASP Top 10 and remains relevant despite modern browser security mechanisms. While the SameSite cookie attribute has significantly reduced the attack surface, CSRF protection remains essential for applications that support cross-origin requests, use cookie-based authentication, or must defend against sophisticated attack scenarios involving subdomain takeover or DNS rebinding.

Technical Deep Dive

A CSRF attack follows a predictable sequence: the victim authenticates with the target application, establishing a session cookie. The attacker then lures the victim to a malicious page (via phishing, social engineering, or compromised advertising) that contains a hidden form or script triggering a request to the target application. The victim's browser automatically attaches the session cookie, and the target application processes the request as legitimate.

Attack Vectors

VectorMechanismStealth Level
Hidden form + auto-submit<form> with JavaScript submit()High -- no user interaction needed
Image tag<img src="https://target.com/action?param=value">High -- works for GET requests
XMLHttpRequestJavaScript AJAX request from attacker's pageMedium -- blocked by CORS for non-simple requests
Link clickSocial engineering to click crafted URLLow -- requires user action
iframeHidden iframe loads target pageMedium -- modern browsers restrict

Defense Mechanisms

DefenseMechanismStrength
Synchronizer TokenServer generates unique token per session/request, validates on submissionStrong -- industry standard
Double-Submit CookieRandom value in both cookie and request parameterStrong -- stateless variant
SameSite CookieBrowser restricts cross-origin cookie sendingStrong -- defense in depth
Origin/Referer HeaderServer validates request originModerate -- headers can be stripped
Custom Request HeadersRequire custom header (e.g., X-Requested-With)Moderate -- CORS preflight protects
Re-authenticationRequire password/2FA for sensitive operationsVery strong -- last resort

Token Generation Requirements

CSRF tokens must be generated using a CSPRNG to prevent prediction attacks. The token must have sufficient entropy (at least 128 bits) and must be bound to the user's session to prevent token fixation.

Token Properties:
  - Length: >= 128 bits (32 hex characters or 22 base64 characters)
  - Source: CSPRNG (never Math.random or similar)
  - Binding: Tied to user session, invalidated on logout
  - Scope: Per-session (minimum) or per-request (maximum security)
  - Transmission: Hidden form field or custom HTTP header
  - Storage: Server-side session or signed cookie (never URL parameter)

Architecture and Implementation

CSRF protection in modern web frameworks operates at the middleware/plug level, intercepting all state-changing requests (POST, PUT, PATCH, DELETE) and validating the presence and correctness of a CSRF token before allowing the request to proceed.

The protection architecture consists of three components: token generation (creating unpredictable tokens and associating them with sessions), token embedding (including tokens in forms and page metadata), and token validation (comparing submitted tokens against expected values). The validation step must use constant-time comparison to prevent timing side-channel attacks that could allow an attacker to incrementally guess the token.

Phoenix Framework implements CSRF protection through the Plug.CSRFProtection plug, which is included by default in all generated applications. The token is automatically embedded in all forms generated by Phoenix.HTML.Form functions and validated on every non-GET request.

Usage in Prismatic Platform

The Prismatic Platform enforces CSRF protection across all web endpoints through Phoenix's built-in plug pipeline. The platform extends the default protection with additional safeguards for the API gateway and LiveView connections.

defmodule PrismaticWeb.Router do
  @moduledoc """
  Router configuration demonstrating CSRF protection layers.
  All browser pipelines include CSRF protection by default.
  API pipelines use token-based authentication instead.
  """

  use PrismaticWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, html: {PrismaticWeb.Layouts, :root}
    # CSRF protection -- validates token on all non-GET requests
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
    # API uses Bearer token auth, not session cookies
    # CSRF not applicable for token-authenticated APIs
    plug PrismaticWeb.Plugs.APIAuth
  end
end
defmodule PrismaticWeb.CSRFEnhancement do
  @moduledoc """
  Enhanced CSRF protection for sensitive operations.
  Implements per-request tokens for critical state changes
  and double-submit cookie validation for API endpoints
  that support both cookie and token authentication.
  """

  import Plug.Conn

  @spec validate_sensitive_operation(Plug.Conn.t(), keyword()) :: Plug.Conn.t()
  def validate_sensitive_operation(conn, _opts) do
    csrf_token = get_session(conn, :csrf_token)
    submitted_token = get_req_header(conn, "x-csrf-token") |> List.first()

    case constant_time_compare(csrf_token, submitted_token) do
      true ->
        # Rotate token after use for sensitive operations
        new_token = generate_csrf_token()
        conn |> put_session(:csrf_token, new_token)

      false ->
        conn
        |> put_status(:forbidden)
        |> Phoenix.Controller.json(%{error: "Invalid CSRF token"})
        |> halt()
    end
  end

  defp generate_csrf_token do
    :crypto.strong_rand_bytes(24)
    |> Base.url_encode64(padding: false)
  end

  defp constant_time_compare(nil, _), do: false
  defp constant_time_compare(_, nil), do: false

  defp constant_time_compare(a, b) when byte_size(a) != byte_size(b), do: false

  defp constant_time_compare(a, b) do
    Plug.Crypto.secure_compare(a, b)
  end
end

LiveView CSRF Considerations

Phoenix LiveView connections use a different CSRF model than traditional form submissions. The initial HTTP request that mounts the LiveView validates CSRF normally. Subsequent WebSocket messages are authenticated by the LiveView session token, which is cryptographically signed and includes the CSRF token. This means LiveView handle_event callbacks are inherently CSRF-protected without additional token passing.

Request TypeCSRF MechanismValidation Point
Form POSTHidden _csrf_token fieldPlug.CSRFProtection
LiveView mountStandard HTTP CSRFRouter pipeline
LiveView eventSigned session tokenLiveView framework
API requestBearer token (not cookie-based)APIAuth plug
WebSocketConnection tokenChannel join

Cross-References

  • CSPRNG -- Secure random generation for CSRF tokens
  • XSS -- Complementary web vulnerability class
  • Session -- Session management CSRF relies on
  • OWASP -- Security standards defining CSRF prevention
  • HTTP -- Protocol carrying CSRF-vulnerable requests
  • Livebooks: security_compliance/ notebooks cover CSRF testing and validation
  • Academy: APISecurityAnalysis topic includes CSRF prevention patterns

See Also


Connect & Contribute

Created by Tomas Korcak (korczis) | Open Source under GHL