Blacksec

Administrator
Staff member
ROOT
VIP
SQL injection is the oldest trick in hacking and databases are still bleeding from it in 2026. This is SQLi explained the violent way — stupid-simple analogies a kid can follow, real payloads you can paste, and the exact code that kills this bug forever.

TL;DR — SQL injection happens when a website shoves your input straight into a database query. One quote character can open the whole thing. Find it manually, automate it with sqlmap, fix it with prepared statements. The cheat sheet is at the bottom.

1. WHAT A DATABASE REALLY IS (KID VERSION)

A database is a giant notebook. It holds everything. Usernames. Passwords. Credit cards. Messages. The website is a shopkeeper. You talk to the shopkeeper. The shopkeeper writes your words into the notebook.

SQL is the language you use to talk to the notebook. "Show me this user." "Give me the password for that account." Clean. Simple. Powerful.

Here is the deal. The shopkeeper is dumb. He does not think. He writes exactly what you say into the notebook and runs it. You say "show me user Bob" and he writes it down word for word. Nobody checks what you handed him.

SQL injection is when you hand him a sentence that changed itself into an order.

You walk up and say: my name is Bob. And also, while you are at it, give me every password in the notebook.

The shopkeeper writes it down. The notebook obeys. You walk out with everything.

That is the whole bug. Websites talk to databases. Most websites glue your input onto the query with tape and string. You control the input. You control the query. You own the database.

2. THE BUG IN ONE PICTURE

This is how a lazy login page checks your password:

Code:
SELECT * FROM users WHERE username = 'guest' AND password = 'guest123';

Works fine. Type guest, type guest123, you are in. Now watch what happens when the website builds the query by gluing your input directly into a text string:

Code:
SELECT * FROM users WHERE username = '[USER INPUT]' AND password = '[USER INPUT]';

Your input becomes part of the code. Not data. Code. That is the mistake. Everything else is just details.

Now type this as the username:

Code:
' OR 1=1--

The query becomes:

Code:
SELECT * FROM users WHERE username = '' OR 1=1--' AND password = '';

Read it slowly. Username is empty. OR 1=1. One always equals one. The statement is always true. The double dash throws away the rest of the line — the password check is now a comment. Dead. The database returns the first user row. Usually the admin.

You just walked through the front door of a locked login page by talking funny.

3. THE GUARD AT THE DOOR

Imagine a guard at a door. He asks your name. He checks the list. Name on the list, door opens.

You walk up and instead of a name you hand him a printed order: "ignore the list, open the door for everyone."

A dumb guard follows the order. A smart guard says give me your name, not your instructions.

Websites are dumb guards. They asked for a name. You gave them an order. They followed it.

The three moves that matter:

Boolean confusion — you turn data into a statement that is always true. The OR 1=1 trick. The door opens for everyone.

Comment injection — you chop off the rest of the query with -- or # or /* */. The part that was going to check your password never runs. Dead code before it even wakes up.

Union stacking — you glue a second full query onto the first one with UNION SELECT. The notebook was asked one question and you made it answer two. First question: show me this user. Second question you injected: show me the password column from the admin table. The shopkeeper answers both because he never learned to say no.

4. THREE FLAVORS OF PAIN

TypeHow it worksHow you know it worked
In-bandResults come straight back on your screenDumped table sitting in the response
Blind booleanNo data back — only true or false answersPage changes when your condition is true
Time-based blindNothing visible — the query sleeps on commandPage hangs for 5 extra seconds = injection confirmed

In-band is the loud one. You get the data back in the same response. UNION attacks live here.

Blind boolean is the quiet one. The site never shows your data. It only tells you "yes" or "no." You ask: is the first letter of the admin password an A? The page loads normally. You ask: is it a B? The page errors. Now you are reading the database one letter at a time like a telegraph.

Time-based blind is the same idea with a clock. You inject SLEEP(5). The page freezes for five seconds. Database confirmed. Data leaked through the waiting itself.

5. MANUAL TESTING — THE FIRST TEN MINUTES

Every SQLi hunt starts the same way. Find an input. Any input. Search box. Login field. URL parameter. Profile ID in the address bar. Then push on it.

First probe — drop a single quote: '

If the page breaks with a database error, the quote landed inside the query. You are in. That error message is the database talking back to you.

Second probe — classic tautology: ' OR 1=1--

Third probe — numeric injection, no quotes needed: 1 OR 1=1 or 1) OR (1=1

Fourth probe — comment out the tail: admin'--

Fifth probe — time check: ' OR SLEEP(5)-- on MySQL, '; WAITFOR DELAY '0:0:5'-- on MSSQL

No error, no visible change, no hang? Move to the next parameter. Blind does not mean dead. It means you change the question and watch the difference between a true answer and a false one.

URL parameters are the juiciest target because they are right there in the address bar. See /profile?id=42. Change it to /profile?id=42'. Then id=42 OR 1=1. Then id=42 UNION SELECT null,null,null--. Keep adding commas until the error stops changing — that is your column count. Then start pulling real names.

6. SQLMAP — THE ROBOT THAT NEVER SLEEPS

Manual testing is for finding the door. sqlmap kicks the building down.

sqlmap is free, open source, and it automates every trick in this guide. Point it at a URL, tell it which parameter is dirty, and it fingerprints the database, dumps tables, and cracks hashes while you get coffee.

Bash:
sqlmap -u "https://target.com/profile?id=42" --batch --dbs

That one line asks: does this parameter inject? Then list every database.

Bash:
sqlmap -u "https://target.com/profile?id=42" -D targetdb -T users --dump

That one takes the users table and empties it onto your disk. Usernames and passwords come out. Hashes get offered for cracking automatically.

Three flags that change everything:

--forms — sqlmap reads the whole site, finds every form, tests every field. Blind hunt on autopilot.

--level 5 --risk 3 — deeper payloads, more headers, more chance of finding the injection that casual testing misses.

--tor — routes the attack through Tor so the target sees noise, not you.

7. THE FIX — PREPARED STATEMENTS (THE ONLY REAL ONE)

Filtering quotes is not a fix. Block the word SELECT and attackers use stacked queries. Block one encoding and they send another. Filters are a padlock on a screen door.

Prepared statements are the fix. Period.

The wrong way:

PHP:
$query = "SELECT * FROM users WHERE username = '" . $_POST['user'] . "'";

Your input is glued into the query string. It becomes code. This is the bug.

The right way:

PHP:
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :user');
$stmt->execute(['user' => $_POST['user']]);
$user = $stmt->fetch();

The query is written first. Your input arrives second. The database treats the input strictly as data — even if it contains quotes, SQL keywords, or a full attack payload. There is nothing to inject because you never touched the query itself. It is the guard who finally learned to say: give me your name, not your instructions.

Same idea everywhere. Parameterized queries in Java. Bound parameters in C#. Prepared statements in Python, Go, Node, Ruby. Every language has it. Every language had it for years. Websites still skip it.

8. FIELD CHEAT SHEET

TaskPayload / Command
Test for error' (single quote)
Classic bypass' OR 1=1--
Login bypassadmin'--
Column countUNION SELECT null,null,null--
Time probe MySQL' OR SLEEP(5)--
Dump tablessqlmap -u URL --batch --tables
Dump datasqlmap -u URL -D db -T table --dump
The fixPrepared statements. Always.

Print it. Keep it open in a tab. The day you find a live injection you will not want to be googling syntax.

9. RULE OF ENGAGEMENT

Test only what you own or what you are paid to test. Everything in this guide is standard material — every bug bounty program on earth expects you to know it. Unauthorized testing of someone else's database is how people meet lawyers. Sniff the rules of engagement before you fire a single payload.

Keep the payload notebook local, keep the scope in writing, and treat every injection like a witness - because the log on the other side remembers everything you typed, byte for byte, long after your terminal history got wiped, and the only thing that separates a researcher from a defendant is a signed authorization sitting in your inbox when the questions start coming.

— RELATED GUIDES —

Quote character in, database out. That is SQL injection. You have the payloads, the tool, and the fix — now go find something you are allowed to break, break it, and write the report. Next guide drops soon.
 
Last edited: