Introduction
SQL Injection occurs when an attacker manipulates SQL queries by injecting malicious input into a web application. If not properly handled, it can lead to unauthorized access, data theft, or even complete database compromise.
In PHP, SQL Injection vulnerabilities are often caused by improper handling of user input. Understanding how SQL Injection works and how to prevent it is essential for building secure applications.
What is SQL Injection in PHP?
SQL Injection is a type of security vulnerability where an attacker inserts malicious SQL code into input fields (like login forms, search boxes, or URLs) to manipulate database queries.
When PHP code directly includes user input in SQL queries without validation or sanitization, attackers can alter the query logic.
Example of Vulnerable Code:
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
In this case, user input is directly embedded into the query, making it vulnerable.
Why it is used (Why attackers use it)
Attackers use SQL Injection for various malicious purposes:
1. Bypass Authentication
Login without valid credentials.
2. Data Theft
Access sensitive data like passwords, emails, or credit card details.
3. Data Modification
Insert, update, or delete database records.
4. Database Control
Gain administrative access to the database.
5. Application Damage
Crash or corrupt the system.
Syntax
Example of SQL Injection Attack
Login Input:
Username: admin
Password: ' OR '1'='1
Resulting Query:
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
Note: Since ‘1’=’1′ is always true, the query returns valid results, allowing unauthorized access.
Examples:
1. Vulnerable Example
$conn = mysqli_connect("localhost", "root", "", "test_db");
$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 "Login successful";
} else {
echo "Invalid credentials";
}
2. Secure Example using Prepared Statements
$conn = mysqli_connect("localhost", "root", "", "test_db");
$stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->bind_param("ss", $username, $password);
$username = $_POST['username'];
$password = $_POST['password'];
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows > 0) {
echo "Login successful";
} else {
echo "Invalid credentials";
}
3. Secure Example using PDO
$conn = new PDO("mysql:host=localhost;dbname=test_db", "root", "");
$stmt = $conn->prepare("SELECT * FROM users WHERE username = :username AND password = :password");
$stmt->execute([
':username' => $_POST['username'],
':password' => $_POST['password']
]);
if($stmt->rowCount() > 0) {
echo "Login successful";
} else {
echo "Invalid credentials";
}
Real-Life Example
Example 1: Login Form Attack
Imagine a login system where users enter their username and password.
Attacker Input:
Username: admin
Password: ' OR '1'='1
If the application is vulnerable, the attacker can log in without knowing the password.
Example 2: Data Extraction
An attacker may use input like:
' UNION SELECT username, password FROM users --
This can expose all user credentials stored in the database.
Example 3: Deleting Data
'; DELETE FROM users; --
This could delete all records from the database if not protected.
Common Mistakes
1. Directly Using User Input in Queries
$query = "SELECT * FROM users WHERE id = " . $_GET['id'];
2. Not Using Prepared Statements
Failing to use parameterized queries increases risk.
3. Relying Only on Client-Side Validation
JavaScript validation can be bypassed easily.
4. Not Escaping Special Characters
Using raw input without sanitization.
5. Displaying Database Errors
Error messages can reveal database structure.
6. Weak Authentication Logic
Improper login validation logic.
Conclusion
SQL Injection is one of the most dangerous vulnerabilities in PHP applications. It can allow attackers to bypass authentication, steal sensitive data, and even destroy databases.
However, it can be easily prevented by following best practices such as using prepared statements, validating input, and avoiding direct query construction with user data.