Objective
Learn how to exploit Information Disclosure Through Error Messages to gather sensitive information about a web application and its backend, and understand how to mitigate this vulnerability through proper error handling.
Scenario
You are assessing a web application that improperly handles errors, revealing stack traces, database queries, and file paths. These exposed details can be used by attackers to craft more effective attacks, such as SQL Injection or directory traversal.
Lab Setup
Prerequisites:
- Basic knowledge of PHP and MySQL.
- 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 users table:
CREATE DATABASE error_handling_lab;
USE error_handling_lab;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL
);
INSERT INTO users (username, password) VALUES ('alice', 'alice123'), ('bob', 'bob123');
PHP Script with Improper Error Handling
Create a file login.php
:
<?php
$conn = mysqli_connect("localhost", "root", "", "error_handling_lab");
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
if (isset($_POST['login'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $query);
if (mysqli_num_rows($result) > 0) {
echo "<h2>Welcome, $username!</h2>";
} else {
die("Error: " . mysqli_error($conn));
}
}
?>
<h2>Login</h2>
<form method="POST" action="">
Username: <input type="text" name="username" required><br>
Password: <input type="password" name="password" required><br>
<button type="submit" name="login">Login</button>
</form>
Running the Application
- Start the Apache server.
- Place
login.php
in the web server’s root directory (htdocs
for XAMPP). - Open
http://localhost/login.php
in your browser.
Exploitation Steps
Step 1: Triggering SQL Errors
Enter the following payload into the Username field:
' OR '1'='1
Enter any value in the Password field and submit the form.
Expected Result:
- The application returns a MySQL error message revealing the query structure, database name, or file paths.
Step 2: Accessing Non-Existent Files
Modify the URL to access a non-existent file:
http://localhost/nonexistent.php
Expected Result:
- The server displays file paths or error stack traces that provide insight into the server’s directory structure.
Solution and Prevention
Problem Analysis
- The application directly outputs error messages containing sensitive information.
Fixing the Vulnerability
Disable Detailed Error Messages in Production
Configure PHP to hide errors in production:
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_reporting(E_ALL);
Implement Custom Error Handling
Use custom error messages for users:
if (mysqli_num_rows($result) > 0) {
echo "<h2>Welcome, $username!</h2>";
} else {
echo "<h2>Invalid username or password.</h2>";
}
Secure Error Logging
Log errors securely without exposing them to users:
error_log("Login failed for user: $username", 3, "/var/log/app_errors.log");
Use Web Server Error Pages
Configure .htaccess
to handle 404 and 500 errors:
ErrorDocument 404 /error_pages/404.html
ErrorDocument 500 /error_pages/500.html
Testing After Fix
Submit the SQL injection payload (' OR '1'='1
).
Expected Result:
The application shows a generic error without revealing backend details.
Visit a non-existent page:
http://localhost/nonexistent.php
Expected Result:
A user-friendly 404 error page appears instead of file paths.
Conclusion
In this lab, you exploited Information Disclosure Through Error Messages by triggering SQL errors and accessing non-existent files to gather sensitive details. You also learned how to prevent this vulnerability by disabling detailed error messages, implementing secure logging, and using custom error pages.
0 Comments