In a nutshell SQL injection happens when a web app builds a database query by gluing your input straight into it. Slip in a piece of SQL instead of a normal value, and the database runs your command — dumping data, bypassing a login, sometimes owning the server. It's the classic "untrusted input treated as code."
The root cause — mixing data and code
A site turns your input into a query. If it builds that query by string-concatenation, your input becomes part of the command, not just a value:
-- the app intends:
SELECT * FROM users WHERE name = 'alice';
-- it builds: "SELECT ... WHERE name = '" + input + "';"
-- you type: alice'--
-- it becomes:
SELECT * FROM users WHERE name = 'alice'--';
That ' closes the string early; the rest of your input is now SQL, and -- comments out the trailing quote so the query stays valid. You wrote code where the app expected a name.
Analogy — a fill-in-the-blank read aloud. A clerk reads: "give me the file for ___." You say "Alice. And also unlock the vault." A careless clerk does both — they can't tell your data from their instructions. SQLi is that confusion.
The fix in one picture
❌ Concatenation
- query built by gluing strings
- input can become command
"... name='" + input + "'"
✅ Parameterized
- query structure fixed
- input passed separately as a value
"... name = ?", [input]
The parameterized query is the wall: the database keeps command and data apart on purpose, so input can never become code.
The classic demonstrations
- Auth bypass. A login checks
WHERE user='X' AND pass='Y'. Enter password' OR '1'='1→ the condition is always true → you're in without the password. (This is thevuln-loginstand's whole point.) - Dumping data (UNION). Append
UNION SELECTto graft your query's results (usernames, password hashes) onto the page. - Blind SQLi. No data shown back, but the page behaves differently for true vs false (or slower with a time delay). You reconstruct data one yes/no at a time — slow, automatable.
Finding it
The first probe is a single quote '. A database error or odd behaviour means input reaches the query unfiltered — a strong signal. Confirm with logic:
' AND '1'='1 → page normal (true)
' AND '1'='2 → page differs (false) ← behaviour changes = injectable
sqlmap automates detection and extraction once you've found an injectable parameter.