Cross Site Request Forgery (CSRF) Complete Guide with Example

Cross-Site Request Forgery (CSRF) is a web security vulnerability that tricks an authenticated user into performing an unwanted action on a website without their knowledge.

CSRF attacks are possible because browsers automatically include certain authentication credentials, such as session cookies, when sending requests to a website.

For example, imagine that you are logged in to your online banking website. You then visit a malicious website in another browser tab. That malicious website could attempt to send a request to your bank to transfer money. If the bank does not properly protect the request against CSRF, the browser may automatically include your banking session cookie.

The attacker does not necessarily need to know your password or steal your session cookie. Instead, they abuse your already-authenticated browser session.

Cross Site Request Forgery

What Is CSRF?

Cross-Site Request Forgery, commonly abbreviated as CSRF, is an attack in which an attacker causes a victim’s browser to send an unauthorized request to a trusted website where the victim is already authenticated.

The key idea is:

The attacker cannot necessarily see the response, but they may be able to make the victim’s browser send the request.

CSRF primarily targets state-changing operations, such as:

  • Changing an email address
  • Changing an account password
  • Updating a profile
  • Adding a new administrator
  • Transferring money
  • Changing account settings
  • Deleting data
  • Placing an order

A properly designed application should require proof that the request actually originated from the legitimate application.

How Does CSRF Work?

A typical CSRF attack involves three parties:

  1. Victim – The user who is logged in.
  2. Trusted Website – The website containing the vulnerable functionality.
  3. Attacker Website – A malicious website controlled by the attacker.

Consider this sequence:

Step 1: Victim Logs In

The user logs in to:

https://example-bank.com

The server creates an authenticated session and sends a cookie:

session_id=ABC123

The browser stores the cookie.

Step 2: Victim Visits a Malicious Website

Later, the user visits:

https://malicious-site.com

The attacker has created a page that attempts to send a request to the bank.

Step 3: Browser Sends the Request

If the browser includes the bank’s authentication cookie with that request, the bank may interpret it as a legitimate request from the logged-in user.

For example, a vulnerable endpoint might accept:

POST /transfer

with data such as:

amount=5000

account=attacker-account

Step 4: Server Processes the Request

If the bank has no CSRF protection, it may process the request because:

  • The session is valid.
  • The user is authenticated.
  • The request contains the required parameters.

The server may therefore believe that the user intentionally requested the transaction.

Example of a CSRF Attack

Imagine a user named Ali has an account at an online banking website.

Ali logs in to:

https://securebank.example

His browser receives an authentication cookie:

session=XYZ789

Ali does not log out.

Later, Ali visits a malicious website containing an automatically submitted request to the bank.

Conceptually, the malicious page might attempt to submit:

POST https://securebank.example/transfer

with:

amount=10000

destination=ATTACKER_ACCOUNT

Because Ali is already logged in, his browser may include the authentication cookie.

If the banking application only checks whether the session is authenticated and does not require a CSRF token or another appropriate defense, the request could be accepted.

The important point

The attacker does not need to know Ali’s password.

They are abusing Ali’s existing authenticated browser session.

CSRF Attack Flow

The attack can be visualized like this:

         1. User logs in

Ali ——————————> Bank Website

 |                                      |

 |<——— Session Cookie ————|

 |

 |

 | 2. Visits malicious website

 v

Malicious Website

 |

 | 3. Causes browser to send request

 v

Bank Website

 |

 | 4. Browser may include authentication

 |    credentials automatically

 v

Server processes unauthorized action

The vulnerability exists when the server cannot reliably distinguish:

Legitimate request

from:

Forged request

CSRF vs XSS

CSRF and Cross-Site Scripting (XSS) are different vulnerabilities, although they can sometimes be used together.

FeatureCSRFXSS
Full nameCross-Site Request ForgeryCross-Site Scripting
Main goalPerform unauthorized actionsExecute attacker-controlled JavaScript
Requires victim authentication?UsuallyNot necessarily
Primary targetState-changing requestsWeb pages/users
Common defenseCSRF tokens, SameSite cookies, origin checksOutput encoding, sanitization, CSP
ExampleChange account emailInject malicious JavaScript

Simple difference

CSRF:

“Make the victim’s browser perform an action.”

XSS:

“Make the victim’s browser execute attacker-controlled script.”

Why Are Cookies Important in CSRF?

CSRF is particularly relevant to applications that use cookie-based authentication.

Suppose the browser stores:

session_id=ABC123

for:

example.com

When making an appropriate request to that domain, the browser can automatically attach the cookie.

The server sees:

Cookie: session_id=ABC123

and identifies the user as authenticated.

The problem is that authentication proves who the user is, but by itself does not necessarily prove where the request originated or that the user intentionally initiated the action.

That’s why applications need additional CSRF defenses for sensitive state-changing operations.

CSRF Token

One of the most common defenses is a CSRF token.

A CSRF token is a unique, unpredictable value associated with the user’s session or request context.

For example:

<form method=”POST” action=”/change-email”>

    <input type=”hidden”

           name=”csrf_token”

           value=”random-secure-token”>

    <input type=”email” name=”email”>

    <button type=”submit”>Change Email</button>

</form>

The server stores or otherwise validates the expected token.

When the form is submitted, the server checks:

Is the CSRF token valid?

If the token is missing or invalid, the server rejects the request.

Why Does a CSRF Token Help?

An attacker can often cause a victim’s browser to send a request, but the attacker should not be able to obtain the legitimate application’s unpredictable CSRF token through normal cross-origin browser behavior.

A legitimate request might contain:

session_id=ABC123

csrf_token=8f72c9…

The malicious request might contain:

session_id=ABC123

csrf_token=missing

The server rejects the second request.

Therefore:

Valid session + Valid CSRF token

        ↓

     Accept

Valid session + Invalid/missing CSRF token

        ↓

     Reject

Example: CSRF Protection in PHP

A basic PHP application can generate a CSRF token after starting a session:

<?php

session_start();

if (empty($_SESSION[‘csrf_token’])) {

    $_SESSION[‘csrf_token’] = bin2hex(random_bytes(32));

}

The token can then be included in a form:

<form method=”POST” action=”update-profile.php”>

    <input

        type=”hidden”

        name=”csrf_token”

        value=”<?= htmlspecialchars($_SESSION[‘csrf_token’], ENT_QUOTES, ‘UTF-8’) ?>”

    >

    <input type=”text” name=”name”>

    <button type=”submit”>Update Profile</button>

</form>

The server should validate the token before performing the action:

<?php

session_start();

if (

    empty($_POST[‘csrf_token’]) ||

    empty($_SESSION[‘csrf_token’]) ||

    !hash_equals($_SESSION[‘csrf_token’], $_POST[‘csrf_token’])

) {

    http_response_code(403);

    exit(‘Invalid CSRF token.’);

}

// Process the requested state-changing operation here.

hash_equals() is preferable to a simple == comparison for security-sensitive token comparisons.

SameSite Cookies

Modern browsers provide another important CSRF mitigation through the SameSite cookie attribute.

For example:

Set-Cookie: session=ABC123; Secure; HttpOnly; SameSite=Lax

Common SameSite values include:

Strict

SameSite=Strict

Provides stronger cross-site cookie restrictions but can affect some legitimate cross-site navigation scenarios.

Lax

SameSite=Lax

Provides useful protection while allowing some cross-site navigation behavior.

None

SameSite=None; Secure

Allows the cookie to be sent in cross-site contexts, so it should be used only when cross-site cookie behavior is actually required and must be paired with Secure.

Important: SameSite cookies are an important defense, but application security should not blindly rely on a single mechanism for every situation.

Origin and Referer Validation

Applications can also validate request headers such as:

Origin

and, where appropriate:

Referer

For example, the server might verify that a sensitive request originated from:

https://example.com

rather than an unrelated website.

This can provide an additional layer of defense.

However, header validation should be implemented carefully because legitimate environments, proxies, privacy settings, and application architectures can affect which headers are available.

CSRF Protection Best Practices

Developers should follow several practices when protecting web applications.

1. Use CSRF Tokens

For cookie-authenticated state-changing requests, use strong, unpredictable CSRF tokens where appropriate.

2. Use SameSite Cookies

Configure authentication cookies with an appropriate:

SameSite

policy.

3. Use HTTPS

Protect authentication and application traffic with HTTPS.

Cookies should generally use:

Secure

when transmitted over HTTPS.

4. Use HttpOnly for Session Cookies

For session cookies that do not need JavaScript access:

HttpOnly

can reduce exposure to client-side scripts.

Remember that HttpOnly does not itself prevent CSRF. It primarily helps protect cookies from being directly accessed through JavaScript.

5. Protect State-Changing Requests

CSRF protection is especially important for operations such as:

POST

PUT

PATCH

DELETE

GET requests should generally be safe and idempotent and should not perform state-changing actions.

Avoid designs such as:

GET /delete-account

Prefer a state-changing method such as:

POST /delete-account

combined with appropriate authorization and CSRF defenses.

6. Validate Server-Side

Never rely exclusively on JavaScript validation.

CSRF protection must ultimately be enforced by the server.

7. Use Authorization Checks

CSRF protection is not a replacement for authorization.

The application should verify both:

Is the user authenticated?

and:

Is the user authorized to perform this action?

Common CSRF Mistakes

Several implementation mistakes can leave an application vulnerable.

Mistake 1: Checking Only the Session

This is insufficient:

if (isset($_SESSION[‘user_id’])) {

    updateAccount();

}

Authentication alone does not establish that the request was intentionally generated by the application.

Mistake 2: Using Predictable Tokens

Avoid tokens such as:

123456

or:

user_id + timestamp

CSRF tokens should be generated using a cryptographically secure random generator.

Mistake 3: Storing Tokens in URLs

Avoid putting sensitive CSRF tokens in URLs such as:

https://example.com/delete?csrf_token=…

URLs can appear in browser history, logs, analytics, bookmarks, and referrer data.

Mistake 4: Protecting Only the Frontend

A hidden form field is not sufficient by itself.

The server must validate the token.

Mistake 5: Assuming POST Automatically Prevents CSRF

Using POST instead of GET is good application design for state-changing operations, but POST alone does not prevent CSRF.

CSRF in Modern Web Applications

Modern applications may use several authentication architectures.

For traditional server-rendered applications using session cookies, CSRF protection is especially important.

For APIs that use an access token supplied explicitly in an HTTP header, such as:

Authorization: Bearer <access-token>

the CSRF threat model can be different because browsers do not automatically attach arbitrary Authorization headers to cross-origin requests in the same way they automatically handle cookies.

However, this does not mean API security can be ignored. Developers still need appropriate controls for:

  • CORS
  • Authentication
  • Authorization
  • Token storage
  • XSS
  • Request validation
  • Rate limiting

CSRF Attack Prevention Checklist

Use this checklist when securing a web application:

  • Use CSRF tokens for appropriate cookie-authenticated state-changing requests.
  • Generate tokens using a cryptographically secure random generator.
  • Validate tokens on the server.
  • Configure appropriate SameSite cookie attributes.
  • Use Secure cookies over HTTPS.
  • Use HttpOnly for cookies that do not need JavaScript access.
  • Do not change server state through GET requests.
  • Validate Origin/Referer where appropriate.
  • Implement proper authorization checks.
  • Protect sensitive account operations with appropriate re-authentication or step-up authentication when warranted.
  • Keep frameworks and security libraries updated.

Simple Analogy

Think of CSRF like someone forging an instruction using your already-authorized identity.

Imagine you have an account at a bank and your bank recognizes you by your signed access card.

You leave the bank with your card still active.

An attacker cannot necessarily copy your card, but they convince you to submit a transaction request that looks like a normal request to the bank.

The bank sees:

Valid customer

+

Valid authorization

=

Process request

A CSRF token acts like an additional secret value that the legitimate bank application provides with the transaction form.

The attacker may be able to make you send a request, but should not know that secret value.

Therefore:

Authentication

      +

CSRF validation

      ↓

Safer state-changing request

Conclusion

Cross-Site Request Forgery (CSRF) is a web application security vulnerability that abuses a user’s authenticated session to perform an unwanted action.

The fundamental problem is that a browser may automatically include authentication credentials, particularly cookies, with requests to a trusted website.

A strong defense typically combines:

  • CSRF tokens
  • SameSite cookies
  • HTTPS
  • Secure cookie configuration
  • Origin/Referer validation where appropriate
  • Proper HTTP methods
  • Server-side validation
  • Strong authorization controls

The most important concept to remember is:

Authentication tells the server who the user is; CSRF protection helps the server verify that a state-changing request was intentionally initiated by the legitimate application context.

Understanding CSRF is essential for anyone learning web development, ethical hacking, penetration testing, application security, or cybersecurity.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top