unicornAll work
All theoryWeb security

SQL injection

Slipping SQL into input so the database runs your command — the classic injection.

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

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.

Defence-in-depth Beyond parameterized queries: give the DB account least privilege (so a successful injection can't drop tables), and add input validation + a WAF as extra layers. But the prepared statement is the wall — the rest are sandbags.
All theory