GO KALI FREE
IntermediateWeb Security

CSRF Explained: Cross-Site Request Forgery Attacks and Defenses

Learn how Cross-Site Request Forgery attacks trick users into executing unwanted actions on authenticated web applications and how to defend against them.

#CSRF#Web Security#Cross-Site Request Forgery#Application Security#OWASP

When a Link Forges Your Identity

You are logged into your bank. An attacker sends you a link to a harmless-looking page that contains <img src="https://your-bank.com/transfer?amount=1000&to=attacker">. Your browser, seeing a request to your bank, automatically includes your session cookie. The bank processes the transfer — because it trusts your authenticated session. This is Cross-Site Request Forgery (CSRF): the attack exploits the trust a website has in your browser.

Prerequisites

Before studying CSRF, you should understand:

  • **Web Security Fundamentals** — How web authentication and sessions work
  • **HTTP Basics** — GET and POST requests, cookies, headers
  • **HTML and JavaScript** — How forms and scripts execute in the browser
  • **Same-Origin Policy** — Understanding browser security restrictions
  • How CSRF Works

    The attack requires three conditions:

  • **An active session** — The victim must be authenticated on the target site
  • **Action knowledge** — The attacker must know the exact parameters of a sensitive action
  • **No proper validation** — The target site must not include CSRF tokens or verification mechanisms
  • The Attack Flow

    The victim logs into their banking website and receives a session cookie. The attacker crafts an HTML page containing a form that auto-submits a fund transfer request to the banking site. The victim visits the attacker's page. The victim's browser automatically sends the request with the session cookie. The bank processes the unauthorized transfer, believing it came from the legitimate user.

    Types of CSRF Attacks

    GET-Based CSRF

    The simplest form uses an image tag or link:

    <img src="https://bank.com/transfer?to=attacker&amount=1000" width="0" height="0">
    

    POST-Based CSRF

    Auto-submitting forms bypass POST-only assumptions:

    <form action="https://bank.com/transfer" method="POST" id="csrf-form">
      <input type="hidden" name="to" value="attacker">
      <input type="hidden" name="amount" value="1000">
    </form>
    <script>document.getElementById('csrf-form').submit();</script>
    

    JSON-Based CSRF

    APIs accepting JSON can be targeted with text/plain encoding:

    <form action="https://api.bank.com/transfer" method="POST" enctype="text/plain">
      <input name='{"to":"attacker","amount":1000}' value=''>
    </form>
    

    CSRF Defenses

    CSRF Tokens

    The most common defense. The server generates a unique, unpredictable token embedded in forms and validated on each state-changing request:

    <form action="/transfer" method="POST">
      <input type="hidden" name="csrf_token" value="a1b2c3d4e5f6...">
      <input type="text" name="to" required>
      <input type="number" name="amount" required>
      <button type="submit">Transfer</button>
    </form>
    

    On the server side:

    const csrf = require('csurf');
    const csrfProtection = csrf({ cookie: true });
    
    app.post('/transfer', csrfProtection, (req, res) => {
      processTransfer(req.body.to, req.body.amount);
    });
    

    SameSite Cookies

    Cookies with SameSite=Strict or SameSite=Lax are not sent on cross-origin requests:

    res.cookie('session', token, {
      httpOnly: true,
      secure: true,
      sameSite: 'Strict'
    });
    

    Origin and Referer Header Validation

    app.post('/transfer', (req, res) => {
      const origin = req.headers.origin;
      const allowedOrigins = ['https://bank.com'];
      if (!origin || !allowedOrigins.includes(origin)) {
        return res.status(403).send('Forbidden');
      }
      processTransfer(req.body.to, req.body.amount);
    });
    

    Real-World Examples

    Netflix CSRF (2006): Attackers could add movies to a user's DVD queue and change account settings by getting users to visit malicious pages while logged into Netflix.

    YouTube CSRF (2008): A vulnerability allowed attackers to perform any action on behalf of a logged-in user, including adding videos to favorites and deleting videos.

    ING Bank CSRF (2015): Researchers demonstrated that ING Direct's banking application was vulnerable to CSRF, allowing attackers to transfer funds and change account settings.

    Common Mistakes

    Relying on POST-only protection: Using POST instead of GET does not prevent CSRF — attackers can craft auto-submitting forms.

    Using weak tokens: Tokens must be cryptographically random per session. Sequential tokens can be predicted.

    Not protecting all endpoints: Forgot password forms, logout actions, and API endpoints must all be protected.

    Sharing tokens across subdomains: A CSRF token valid on app.example.com should not work on admin.example.com.

    Best Practices

  • **Use CSRF tokens for all state-changing requests** — Generate cryptographically random tokens per session
  • **Set SameSite cookies to Strict or Lax** — Prevents cookies on cross-origin requests
  • **Validate Origin/Referer headers** — Defense-in-depth
  • **Require re-authentication for sensitive actions** — Password changes, large transfers
  • **Use custom request headers** — For API endpoints
  • Related Tools

  • **Burp Suite** — Intercept and modify requests to test CSRF protections
  • **OWASP ZAP** — Automated CSRF scanning
  • **curl** — Craft custom requests with specific headers
  • Related Articles

  • Web Security Fundamentals
  • XSS Basics
  • Burp Suite Introduction
  • SQL Injection Basics
  • Summary

    CSRF exploits the trust a web application has in an authenticated user's browser. The primary defense is CSRF tokens — unique, unpredictable values embedded in forms and validated server-side. Modern SameSite cookie attributes provide additional protection. Always protect all state-changing endpoints and implement defense in depth.

    Knowledge Check

  • What three conditions are required for a CSRF attack to succeed?
  • How does a SameSite cookie attribute help prevent CSRF?
  • Why does using POST instead of GET not prevent CSRF?
  • What is the difference between CSRF and XSS?
  • How does the Double Submit Cookie technique work without server-side state?
  • Frequently Asked Questions

    What is CSRF and how does it work?

    CSRF (Cross-Site Request Forgery) tricks an authenticated user into executing unintended actions on a web application. When you are logged into a bank, your browser automatically sends session cookies with every request. An attacker crafts a malicious page that submits a transfer request to the bank — your browser sends the cookies automatically, and the bank processes the unauthorized transfer.

    What are the three conditions required for a CSRF attack?

    The victim must have an active session on the target site, the attacker must know the exact parameters of a sensitive action (URL, form fields), and the target site must not include CSRF tokens or other verification mechanisms. Without any one of these conditions, the attack fails.

    How does a SameSite cookie attribute help prevent CSRF?

    Cookies with `SameSite=Strict` or `SameSite=Lax` are not sent on cross-origin requests. This means a malicious page on attacker.com cannot cause your browser to send cookies to bank.com. Modern browsers default to `SameSite=Lax`, which blocks cookies on cross-origin POST requests (forms) while allowing them on top-level navigation.

    Why does using POST instead of GET not prevent CSRF?

    Attackers can craft auto-submitting HTML forms that send POST requests. A hidden form with `method='POST'` and a script that calls `.submit()` bypasses any assumption that POST-only endpoints are safe. Both GET and POST endpoints performing state-changing actions need CSRF protection.

    What is the difference between CSRF and XSS?

    CSRF exploits the trust a website has in an authenticated user's browser — the browser sends cookies automatically. XSS exploits the trust a user has in a website — the browser executes malicious scripts because they come from a trusted origin. CSRF does not require injecting scripts; it tricks the browser into making legitimate-looking requests.

    How does the Double Submit Cookie technique work?

    The server sets a random token as a cookie and also embeds it in a form field. When the form submits, the server compares the cookie value with the form value. An attacker on a different domain cannot read or set cookies for the target domain (same-origin policy), so they cannot forge the matching pair. This works without server-side session state.

    What is a CSRF token?

    A CSRF token is a unique, unpredictable value generated by the server and embedded in forms. On each state-changing request, the server validates the token matches. Since an attacker cannot guess or read this token (protected by same-origin policy), they cannot forge valid requests. Tokens should be cryptographically random and per-session.

    How do I test for CSRF vulnerabilities?

    Use Burp Suite to intercept requests and identify state-changing actions without CSRF tokens. Test by removing or modifying tokens, changing request methods (GET to POST), and verifying the same token works across different user sessions. Check that tokens are validated on the server, not just present in the form.

    What are real-world examples of CSRF attacks?

    Netflix CSRF (2006) allowed attackers to add movies to users' DVD queues. YouTube CSRF (2008) let attackers perform any user action including deleting videos. ING Bank CSRF (2015) demonstrated fund transfers through the banking application. All exploited missing CSRF tokens on state-changing endpoints.

    Why is CSRF harder to exploit than it sounds?

    CSRF requires the victim to be actively authenticated, the attacker must know exact action parameters, and modern defenses (SameSite cookies, CSRF tokens) are widely implemented. However, password change forms, email updates, and API endpoints are frequently overlooked. The impact per successful attack can be severe despite the conditions required.

    Should I protect all endpoints with CSRF tokens?

    Yes — protect all state-changing endpoints (POST, PUT, DELETE). Even 'low-risk' actions like updating a profile picture or changing notification preferences can be exploited. Password changes and fund transfers require extra protection like re-authentication. GET requests should never cause state changes.

    How do custom request headers help prevent CSRF?

    For API endpoints, requiring a custom header (like `X-Requested-With`) prevents CSRF because cross-origin requests cannot set custom headers due to CORS restrictions. An attacker can force the browser to send cookies, but cannot add arbitrary headers to the request. This is a lightweight defense for JSON APIs.