SQL Injection (original) (raw)

Last Updated : 30 Apr, 2026

SQL Injection (SQLi) is a web application vulnerability where attackers inject malicious SQL queries through user inputs to manipulate backend database operations, potentially leading to unauthorized access, modification, or deletion of data. It is one of the most critical and widely exploited security flaws in web applications.

SQL_Injection

SQL Injection Security Levels (DVWA)

DVWA (Damn Vulnerable Web Application) provides different security levels for SQL Injection to help learners understand how security measures affect vulnerability and exploitation techniques.

1. Low Security

At this level, user input is directly included in the SQL query without any validation or sanitization, making it highly vulnerable to SQL injection attacks. id=id = id=_GET['id']; query="SELECTfirstname,lastnameFROMusersWHEREuserid=′query = "SELECT first_name, last_name FROM users WHERE user_id = 'query="SELECTfirstname,lastnameFROMusersWHEREuserid=id';";

2. Medium Security

At this level, basic input sanitization is applied using functions like addslashes(), which escapes special characters such as '. id=addslashes(id = addslashes(id=addslashes(_GET['id']); query="SELECTfirstname,lastnameFROMusersWHEREuserid=′query = "SELECT first_name, last_name FROM users WHERE user_id = 'query="SELECTfirstname,lastnameFROMusersWHEREuserid=id';";

**Example:

3. High Security

At this level, the application uses prepared statements (parameterized queries), which separate SQL logic from user input. stmt=stmt = stmt=pdo->prepare("SELECT first_name, last_name FROM users WHERE user_id = ?"); stmt−>execute([stmt->execute([stmt>execute([id]);

**Security impact:

Types of SQL Injection

There are different types of SQL Injection

1. Error-Based SQL Injection

Error-based SQL injection is a type of in-band SQL injection where an attacker intentionally causes the database to generate an error message. The attacker then analyzes this error message to gain valuable information about the database's structure, like table names and column names, which can be used to craft further, more precise attacks.

**How It Works:

This attack targets applications that reveal raw database errors instead of showing generic messages. By injecting malicious input that breaks the SQL syntax, attackers trigger these errors and gain valuable clues about the database structure.

Example (DVWA Setup)

**Step 1: Set Up Environment

file

file

file

**Step 2: Identify Vulnerability

The SQL Injection page has a simple input box where you can enter a user ID.

**The backend query is typically:

SELECT * FROM users WHERE id = 'user_input';

file

**SQL Injection Source:

PHP `

id=id = id=_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database query="SELECTfirstname,lastnameFROMusersWHEREuserid=′query = "SELECT first_name, last_name FROM users WHERE user_id = 'query="SELECTfirstname,lastnameFROMusersWHEREuserid=id';"; result=mysqliquery(result = mysqli_query(result=mysqliquery(GLOBALS["___mysqli_ston"], query)ordie(′<pre>′.((isobject(query ) or die( '<pre>' . ((is_object(query)ordie(<pre>.((isobject(GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '' ); // Get results while( row=mysqlifetchassoc(row = mysqli_fetch_assoc( row=mysqlifetchassoc(result ) ) { // Get values first=first = first=row["first_name"]; last=last = last=row["last_name"]; // Feedback for end user echo "
ID: {$id}
First name: {$first}
Surname: {$last}
"; } mysqli_close($GLOBALS["___mysqli_ston"]); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); query="SELECTfirstname,lastnameFROMusersWHEREuserid=′query = "SELECT first_name, last_name FROM users WHERE user_id = 'query="SELECTfirstname,lastnameFROMusersWHEREuserid=id';"; #print $query; try { results=results = results=sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values first=first = first=row["first_name"]; last=last = last=row["last_name"]; // Feedback for end user echo "
ID: {$id}
First name: {$first}
Surname: {$last}
"; } } else { echo "Error in fetch ".$sqlite_db->lastErrorMsg(); } break; } } ode ?>

`

**Step 3: Trigger the Error

Now, try to break the query. Enter a single quote ' in the input box and submit.

file

**The query becomes:

SELECT * FROM users WHERE id = ''';

**This is called Error-Based SQL Injection because:

2. Union-Based SQL Injection

Union-based SQL Injection is a technique where attackers use the UNION operator to combine the results of two or more SELECT statements into a single result set. This can allow them to extract information from other tables in the database. The UNION operator can only be used if:

UNION Operator: The UNION operator is used to combine the result-set of two or more SELECT statements.

**UNION Syntax:

SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

**Example (DVWA Setup):

**Step 1: Identify Vulnerability

SELECT * FROM users WHERE id = 'user_input';

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

**Step 2: Find Number of Columns

**Try to sort the results by column:

1 ORDER BY 1

file

SQL Injection Source

PHP `

id=id = id=_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database query="SELECTfirstname,lastnameFROMusersWHEREuserid=′query = "SELECT first_name, last_name FROM users WHERE user_id = 'query="SELECTfirstname,lastnameFROMusersWHEREuserid=id';"; result=mysqliquery(result = mysqli_query(result=mysqliquery(GLOBALS["___mysqli_ston"], query)ordie(′<pre>′.((isobject(query ) or die( '<pre>' . ((is_object(query)ordie(<pre>.((isobject(GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '' ); // Get results while( row=mysqlifetchassoc(row = mysqli_fetch_assoc( row=mysqlifetchassoc(result ) ) { // Get values first=first = first=row["first_name"]; last=last = last=row["last_name"]; // Feedback for end user echo "
ID: {$id}
First name: {$first}
Surname: {$last}
"; } mysqli_close($GLOBALS["___mysqli_ston"]); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); query="SELECTfirstname,lastnameFROMusersWHEREuserid=′query = "SELECT first_name, last_name FROM users WHERE user_id = 'query="SELECTfirstname,lastnameFROMusersWHEREuserid=id';"; #print $query; try { results=results = results=sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values first=first = first=row["first_name"]; last=last = last=row["last_name"]; // Feedback for end user echo "
ID: {$id}
First name: {$first}
Surname: {$last}
"; } } else { echo "Error in fetch ".$sqlite_db->lastErrorMsg(); } break; } } ?>

`

1 ORDER BY 2

Submit. It should work.

file

**Step 3: Prepare for UNION Injection

3. Blind-Based SQL Injection

Blind SQL Injection occurs when attackers cannot see query results directly on the webpage. Instead, they infer information from subtle changes in the application’s behavior or response time. Although slower and more tedious than classic SQLi, it can be equally effective.

**Types of Blind SQL Injection:

**1. Boolean-Based Blind SQL Injection

**2. Time-Based Blind SQL Injection

**Example:

Consider a login page where you enter a username and password.

**The application constructs a SQL query like this:

SELECT * FROM users WHERE username = 'user_input' AND password = 'password_input';

**Boolean-Based Testing:

user_input = 'admin' AND 1=1; --

user_input = 'admin' AND 1=2; --

file

By using a series of these true/false questions, an attacker can systematically guess and extract information, one character at a time. The process can be automated to guess everything from table names to user passwords.

Impact of SQL Injection Attacks

Preventing SQL Injection Attacks

There are several best practices to prevent SQL injection attacks:

1. Use Prepared Statements and Parameterized Queries

**Example in PHP (using MySQLi): stmt=stmt = stmt=conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); stmt−>bindparam("ss",stmt->bind_param("ss", stmt>bindparam("ss",username, $password);
$stmt->execute();

2. Employ Stored Procedures

**Example:

CREATE PROCEDURE GetUserByUsername (IN username VARCHAR(50))
BEGIN
SELECT * FROM users WHERE username = username;
END;

3. Whitelist Input Validation

4. Use ORM Frameworks

5. Restrict Database Privileges

6. Error Handling