Introduction to SQL Injection
Summary
SQL Injection (SQLi) is generally rated as a severe vulnerability in web applications as it allows attackers to execute malicious queries that can compromise both web application and database security. It is one of the oldest and dangerous vulnerabilities.
What is SQL database?
SQL database is a type of relational database management system used for storing and managing data. It utilises SQL language to define, manipulate and query data, organising it into tables composed of rows and columns.
What is SQL?
Structured Query Language (SQL) is a versatile and case-insensitive language for querying databases, commonly used for selecting, inserting, updating and deleting data. While syntax may vary between different databases, this explanation focuses on MySQL.
Assume that we have created a table called staff in the database.
For a better illustration, we can use SQL Fiddle to show the queries and the outputs.
-
INSERT
INSERT
clause is used to add data into the database.Example:
INSERT INTO staff (username, password) VALUES ('user', 'user123');
The query inserts a new record into tablestaff
with usernameuser
and passworduser123
. -
SELECT
SELECT
clause is used to retrieve data from the database.Examples:
SELECT * FROM staff;
The asterisk*
indicates that we request for all data in the tablestaff
.
SELECT * FROM staff LIMIT 1,2;
TheLIMIT 1,2
clause restricts the database to skip the first row and return just two rows of data.
SELECT * FROM staff WHERE username != 'vendor';
TheWHERE
clause is used to specify specific conditions. The!= 'vendor'
instructs the database to retrieve data that the username is NOT equal tovendor
.
SELECT * FROM staff WHERE username = 'admin' OR username = 'administrator';
TheOR
operator specifies that the data returned must match eitheradmin
oradministrator
.
SELECT * FROM staff WHERE username = 'rehack' AND password = 'reh4ckisc00l';
TheAND
operator specifies that the data returned must match bothrehack
andreh4ckisc00l
.
SELECT * FROM staff WHERE username LIKE 'v%';
TheLIKE 'v%'
clause allows us to retrieve data that starts with the letter'v'
. The%
symbol acts as a wildcard, matching any characters.
SELECT * FROM staffs WHERE username LIKE '%a%';
TheLIKE '%a%'
clause allows us to retrieve data containing'a'
in it.
-
UPDATE
UPDATE
clause is used to modify data in the database.Example:
UPDATE staff SET password = 'isnotmyname' WHERE username = 'user';
The query updates the password ofuser
toisnotmyname
.
-
DELETE
DELETE
clause is used to remove data from the database.Examples:
DELETE FROM staff WHERE username = 'vendor';
The query removes a row with usernamevendor
.
DELETE FROM staff;
If we omit theWHERE
clause, all data in the table will be deleted. Do note that the record count is 0, meaning there are zero data remaining in the table.
-
UNION
UNION
clause is used to combine data from multipleSELECT
queries.Example:
Assume that we have two tables of different departments.Table 1 -
english
Table 2 -
history
SELECT staff_name, dept_id FROM english UNION SELECT staff_name, dept_id FROM history;
The query combines and retrievesstaff_name
anddept_id
from two tables. Do note that there are no duplicate data in the output.
Now that we have covered some SQL basics, let’s explore SQL injection.
What is SQL injection?
SQL injection is a hacking technique in which attackers exploit weak input validation in web applications to inject malicious SQL queries into database. This allows for unauthorised access, data manipulation or data theft, posing a significant threat to application and database security.
What does SQL injection look like?
Let’s explore with a simple SQL injection scenario from PortSwigger Academy.
Resources: PortSwigger: SQL Injection - Login Bypass
Scenario:
SQL injection vulnerability allowing login bypass.
This lab contains a SQL injection vulnerability in the login function.
To solve the lab, perform a SQL injection attack that logs in to the application as theadministrator
user.
After gaining access to the lab, we will be greeted with an e-commerce website.
To access the login page, click on ‘My Account,’ where we will find the login form.
Considering the vulnerability exists on the login form, we will assume the SQL query used might look like this:
SELECT * FROM users WHERE username = '$username' AND password = '$password';
To bypass the login as administrator
, we can inject the username field with administrator' --
and random input for the password field.
After injecting administrator' --
into the username field, the SQL query becomes:
SELECT * FROM users WHERE username = ' administrator' --' AND password = 'random';
In SQL, the --
functions as a comment, causing the rest of queries to be ignored.
As a result, we successfully bypassed the password check with the SQL query:
SELECT * FROM users WHERE username = 'administrator' --
Upon clicking the ‘Login’, observe that we are now login as the administrator.
How to detect SQL injection vulnerabilties?
-
Error-based testing
Submit a single quote'
character into input fields or URLs and check for error messages or unusual behavior. If the application mishandles this input, it might be vulnerable to SQL injection. This generally possible when the application enables the debug messages.Example:
Inject'
into URL likehttp://web.abc/event.php?id=1
and see if there error messages like'You have an error in your SQL syntax; ~
. -
Boolean-based testing
Test Boolean conditions likeOR 1=1
andOR 1=2
within input fields and observe any differences in the application’s response. If the application behaves differently for these conditions, it may indicate a potential vulnerability. Do note that, whenever possible avoid usingOR 1=1
on sensitive forms such as Login or Reset Password pages. As this may creates unncessary changes in the database if the application is poorly coded. You may useAND 1=1
as an alternative.Example:
Inject'OR 1=1 --
in a login field and see if it grants access without valid credentials. -
Time-based testing
Submit a payload designed to trigger time delays and monitor the application’s response times for variations. If there are significant delays, it could suggest an SQL injection vulnerability.Example:
InjectSLEEP(5)
into the database and see if there’s a delay of 5 seconds before the application responds.
How to prevent from SQL injection?
-
Prepared statements
Prepared statements also known as parameterised queries, involving predefined SQL query and adding user inputs as separate parameters. This method safeguards the SQL query’s structure and improves security.Example:
$stmt = $conn -> prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)"); $stmt -> bind_param("sss", $username, $password, $email);
-
Escaping user input
Escaping user input involves adding a backslash () to special characters to treat them as regular strings, preventing them from breaking SQL queries or being used in injection attacks. There are cases where a bypass may exist on a certain condition. Hence, this approach may not very reliable, depending on how the application is coded.Example:
We can use'mysqli_real_escape_strings'
function in PHP to escape any special character. -
Input validation
Input validation restricts user input to predefined values or patterns. An allowlist can be used to only accept specific strings.Example:
We can usefilter_var($email, FILTER_VALIDATE_EMAIL)
function in PHP to validate e-mail address
References
- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
- https://portswigger.net/web-security/sql-injection
- http://sqlfiddle.com/
Author: Alysha from RE:HACK