DEV Community

Cover image for Understanding Cross-Site Request Forgery (CSRF) Attacks: How They Work and How to Prevent Them
Igor Venturelli
Igor Venturelli

Posted on • Originally published at igventurelli.io

Understanding Cross-Site Request Forgery (CSRF) Attacks: How They Work and How to Prevent Them

CSRF exploits browser trust to hijack user actions. Learn how it works and how to defend your web apps

Cross-Site Request Forgery (CSRF) is a critical web security vulnerability that exploits the trust a web application has in an authenticated user. Unlike other attacks that directly target a web application’s security mechanisms, CSRF tricks a logged-in user into unknowingly executing unwanted actions on a website where they are authenticated. This attack is particularly dangerous because it takes advantage of how browsers handle authentication tokens, such as cookies, making it a persistent risk for web applications that rely on session-based authentication.

In this article, we’ll break down how CSRF works, why it is exclusive to web applications, and how attackers leverage social engineering to exploit this vulnerability. We’ll also discuss why modern security mechanisms, such as Same-Origin Policy (SOP) and Cross-Origin Resource Sharing (CORS), play a vital role in mitigating these attacks.

How CSRF Attacks Work

CSRF attacks exploit the way browsers automatically include authentication credentials (such as cookies, session IDs, or HTTP authentication headers) when making requests to a website where a user is already authenticated. The attacker’s goal is to trick the victim into unknowingly submitting a malicious request to the targeted application.

The target requests for the attackers are the ones that perform changes on the application, like fund transfer. As the attacker doesn’t receive the responses, requests that doesn’t change anything and only return data are worthless for them.

Why CSRF Only Affects Web Applications

CSRF attacks are exclusive to web applications because they rely on the browser automatically sending stored credentials. When a user logs into a website, their browser retains authentication tokens (such as session cookies). If the same user visits a malicious website while still logged in, the malicious site can initiate requests to the target site without the user’s knowledge.

In contrast, stateless APIs that require access tokens in HTTP headers (such as Bearer tokens in OAuth2) are not vulnerable to CSRF. This is because browsers do not automatically include authorization headers when making cross-origin requests, making CSRF ineffective against such APIs.

A Hypothetical CSRF Attack Example

Scenario: An Online Banking Application

Imagine a user logs into their online banking account at https://bank.example.com. The application uses cookies to maintain session authentication. While the user is logged in, they receive an email with a seemingly harmless link:

Click here to claim your reward: <https://bank.example.com/transfer?to=attacker&amount=1000>
Enter fullscreen mode Exit fullscreen mode

Since the browser automatically includes the session cookie when visiting bank.example.com, clicking the link transfers $1000 to the attacker’s account without requiring any additional user authentication.

CSRF Using a Malicious Form Submission (POST Request Attack)

Attackers can also leverage hidden HTML forms to perform CSRF attacks. Consider the following scenario:

A victim visits a malicious website containing the following HTML:

<form action="<https://bank.example.com/transfer>" method="POST">
    <input type="hidden" name="to" value="attacker">
    <input type="hidden" name="amount" value="1000">
</form>
<script>
    document.forms[0].submit();
</script>
Enter fullscreen mode Exit fullscreen mode

As soon as the victim visits the page, the form is automatically submitted, executing the unauthorized transaction. Since the request is made from the victim’s browser and their session is active, the bank processes the transaction.

The Role of Social Engineering in CSRF Attacks

CSRF attacks depend on social engineering to trick victims into performing unintended actions. Common tactics include:

  • Malicious Emails: Attackers send phishing emails containing deceptive links or forms.
  • Embedded Images or Scripts: A CSRF attack can be embedded in an image tag:

    <img src="<https://bank.example.com/transfer?to=attacker&amount=1000>">
    
  • Compromised Third-Party Websites: Attackers inject CSRF payloads into forums, advertisements, or compromised web pages that unsuspecting users visit.

CSRF Attack Sequence Diagram

To make it easier to understand, let’s take a look on the sequence diagram below:

Image description

Why CSRF Doesn’t Work with Certain HTTP Methods

Modern browsers enforce the Same-Origin Policy (SOP) to restrict cross-origin interactions. As part of this policy, browsers allow GET and POST requests to be made automatically when an authenticated user clicks a link or loads a form. However, PUT, DELETE, and PATCH requests are blocked unless explicitly allowed via CORS preflight checks.

This is why CSRF attacks typically involve GET or POST requests rather than PUT or DELETE requests, which require preflight checks that attackers cannot bypass without explicit server-side misconfiguration.

The Risk of Misconfigured CORS Headers

CORS (Cross-Origin Resource Sharing) is a mechanism that controls which external domains can access resources on a server. However, some developers mistakenly set the Access-Control-Allow-Origin header to *, which permits requests from any origin. This is dangerous because it effectively disables the Same-Origin Policy, allowing attackers to perform unauthorized cross-origin requests that might otherwise be blocked.

Example of a Dangerous CORS Configuration

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Credentials: true
Enter fullscreen mode Exit fullscreen mode

Setting Access-Control-Allow-Credentials: true while allowing any origin (*) is a major security risk because it allows any website to send authenticated requests using the victim’s credentials. A secure approach is to only allow trusted domains:

Access-Control-Allow-Origin: <https://trusted.example.com>
Enter fullscreen mode Exit fullscreen mode

Protecting Against CSRF Attacks

To prevent CSRF, developers should implement the following security measures:

  1. Use CSRF Tokens – CSRF tokens are random values generated for each user session and must be included in requests that modify server-side data.
  2. Require SameSite Cookies – Setting cookies with the SameSite=strict or SameSite=lax attribute prevents them from being sent on cross-origin requests.
  3. Use CORS Securely – Restrict CORS permissions to trusted domains and never set Access-Control-Allow-Origin: * for authenticated resources.
  4. Implement User Authentication for Sensitive Actions – Require re-authentication or multi-factor authentication (MFA) before performing critical actions like transactions or account changes.

Conclusion

CSRF remains a prevalent attack in web applications due to how browsers handle session authentication. By exploiting user trust and leveraging social engineering, attackers can execute unauthorized actions on behalf of victims. However, with proper security controls such as CSRF tokens, SameSite cookies, and secure CORS configurations, developers can effectively mitigate this risk.

As web security threats evolve, maintaining a strong understanding of vulnerabilities like CSRF and implementing best practices is crucial to protecting both users and applications.


Let’s connect!

📧 Don’t Miss a Post! Subscribe to my Newsletter!
📖 Check out my latest OAuth2 book!
➡️ LinkedIn
🚩 Original Post

Imagine monitoring actually built for developers

Billboard image

Join Vercel, CrowdStrike, and thousands of other teams that trust Checkly to streamline monitor creation and configuration with Monitoring as Code.

Start Monitoring

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay