What is Cross-site request forgery (CSRF) Vulnerability?

Cross-Site Request Forgery (CSRF) is an attack that compels an authorized end-user to do undesirable activities on a web application. An attacker can deceive users of a web application into performing activities of the attacker’s choosing with the use of social engineering (such as delivering a link through email or chat). If the target is a regular user, a successful CSRF attack can force the user to conduct state-changing actions such as transferring payments or changing their email address. CSRF can compromise the entire web application if the victim is an administrative account.

Cross-Site Request Forgery (CSRF) is a security vulnerability that occurs when an attacker tricks a user into unintentionally performing actions on a web application without their knowledge or consent. This happens because the web application fails to verify that the requests it receives are genuinely initiated by the user, allowing malicious actions to be executed on behalf of the victim. In this article, we’ll explore CSRF in-depth, discuss its implications, and provide sample code snippets in various popular programming languages and frameworks to help developers understand and prevent this security threat.

How CSRF Works

  1. Victim Logs In: The victim logs into a web application, which generates authentication tokens and stores them in the user’s browser.
  2. Attacker’s Payload: The attacker tricks the victim into visiting a malicious website or clicking on a crafted link containing malicious code. This code includes requests to the target web application.
  3. Unauthorized Requests: The victim’s browser, still authenticated with the web application, unknowingly sends requests (e.g., changing email, password, or making financial transactions) initiated by the attacker’s code.
  4. Malicious Actions: The web application processes the requests, believing they are legitimate, and carries out the malicious actions on the victim’s behalf.

Preventing CSRF

To prevent CSRF vulnerabilities, developers should implement proper request validation, use anti-CSRF tokens, and adhere to secure coding practices. Here are code samples in various programming languages and frameworks:

Python (Django)

# Django includes built-in CSRF protection

# In your HTML form
<form method="post" action="/update_profile/">
    {% csrf_token %}
    <!-- Other form fields -->
    <button type="submit">Update Profile</button>
</form>

Node.js (Express)

const express = require('express');
const cookieParser = require('cookie-parser');
const csrf = require('csurf');

const app = express();
app.use(cookieParser());

// Enable CSRF protection
const csrfProtection = csrf({ cookie: true });
app.use(csrfProtection);

app.post('/update_profile', (req, res) => {
    // Verify CSRF token
    if (!req.csrfToken() === req.body._csrf) {
        return res.status(403).send('Invalid CSRF Token');
    }

    // Process the request
    // ...
});

PHP (Laravel)

// Laravel automatically generates CSRF tokens

// In your HTML form
<form method="POST" action="/update_profile">
    @csrf
    <!-- Other form fields -->
    <button type="submit">Update Profile</button>
</form>

ASP.NET (C#)

// ASP.NET includes built-in CSRF protection

// In your HTML form
<form method="post" action="/update_profile">
    @Html.AntiForgeryToken()
    <!-- Other form fields -->
    <button type="submit">Update Profile</button>
</form>

Ruby on Rails (Ruby)

# Ruby on Rails includes built-in CSRF protection

# In your HTML form
<%= form_tag '/update_profile' do %>
  <%= csrf_meta_tags %>
  <!-- Other form fields -->
  <%= submit_tag 'Update Profile' %>
<% end %>

Java (Spring Framework)

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.security.web.csrf.CsrfToken;

@RestController
public class ProfileController {
    @PostMapping("/update_profile")
    public String updateProfile(@RequestParam("_csrf") CsrfToken csrfToken) {
        // Verify CSRF token
        if (!csrfToken.getToken().equals(csrfToken)) {
            return "Invalid CSRF Token";
        }

        // Process the request
        // ...

        return "Profile updated successfully";
    }
}

Ruby (Sinatra Framework)

# Example in Sinatra using the 'sinatra_csrf' gem for CSRF protection
require 'sinatra'
require 'sinatra/csrf'

enable :sessions

helpers Sinatra::CSRF

post '/update_profile' do
  # Verify CSRF token
  if csrf_token != params['_csrf']
    return 'Invalid CSRF Token'
  end

  # Process the request
  # ...
end

React (JavaScript)

import { useState } from 'react';

function ProfileUpdate() {
  const [csrfToken, setCsrfToken] = useState('');

  // Fetch CSRF token from server and set it in the state

  const handleUpdate = async () => {
    // Verify CSRF token
    if (csrfToken !== sessionStorage.getItem('csrfToken')) {
      alert('Invalid CSRF Token');
      return;
    }

    // Send the update request
    // ...
  };

  return (
    <div>
      <input
        type="hidden"
        name="_csrf"
        value={csrfToken}
      />
      {/* Other form fields */}
      <button onClick={handleUpdate}>Update Profile</button>
    </div>
  );
}

These additional code samples demonstrate CSRF prevention techniques in Ruby on Rails, Java (Spring Framework), Ruby (Sinatra Framework), and React. Implementing these measures in your applications helps safeguard against CSRF vulnerabilities, ensuring that actions are only performed when initiated by legitimate users.

These code samples demonstrate CSRF prevention techniques in Python (Django), Node.js (Express), PHP (Laravel), and ASP.NET (C#). Implementing these measures helps protect your web applications from CSRF vulnerabilities by ensuring that actions are only performed when initiated by legitimate users.

Leave a Comment

Scroll to Top