Beacon Robotics' HR tool lets a manager search employees by last name. Built carelessly, that one search box is enough to let a stranger read every employee's salary, or worse. SQL injection is exactly how.
Learning Objectives
- Define SQL injection precisely: it's a vulnerability in how a query is built, not a flaw in SQL itself.
- Trace a real example showing exactly how one input string changes a query's meaning.
- Name the three real categories of SQL injection, and what distinguishes each.
User Input
A search box, a login form
Concatenated Into SQL Text
Not kept separate from it
Attacker Reshapes the Query
Input becomes SQL, not just data
Unauthorized Data Exposed
Or worse: modified or deleted
What SQL Injection Actually Is
SQL injection is a vulnerability that happens when untrusted input (anything a user types) is concatenated directly into a query's text, rather than kept separate from it. The database can't tell the difference between "SQL the developer wrote" and "SQL an attacker smuggled in through a text box", once it's all one string, it's all just SQL to execute.
A Concrete Example
The HR search feature builds its query like this, string concatenation, with the search box's value dropped straight in:
query = "SELECT * FROM employees WHERE last_name = '" + userInput + "'"
A normal search for "Patel" produces exactly the intended query. But nothing stops userInput from containing SQL of its own. Typing this into the search box:
' OR '1'='1
turns the intended query into this, once concatenated:
SELECT * FROM employees WHERE last_name = '' OR '1'='1'
'1'='1' is always true, for every single row, so the WHERE clause no longer filters anything at all, every employee's full row, salary included, comes back for a search box that was only ever supposed to match a last name.
The Three Real Categories
| Type | How It Works |
|---|---|
| In-band (classic) | The attacker sees the result directly, either in an error message (error-based) or by appending a UNION SELECT to pull extra columns/tables into the visible output (union-based). |
| Blind | No result or error is visible at all, the attacker infers information one true/false question at a time (boolean-based), or by measuring how long the query takes to respond (time-based, e.g. forcing a deliberate delay). |
| Out-of-band | The database is made to send data somewhere else entirely, a DNS or HTTP request to a server the attacker controls, used when neither direct output nor timing is observable. |
Why String Concatenation Is the Root Cause
Every version of this vulnerability traces back to the same root cause: building a query by gluing text together, where some of that text came from outside the application's control. The real fix isn't trying to detect or clean dangerous-looking input, it's never concatenating untrusted input into SQL text in the first place. That's exactly what the next two lessons, SQL Parameters and Prepared Statements, cover.
Try It Yourself
Given this vulnerable query, query = "SELECT * FROM employees WHERE department_id = " + userInput, what value of userInput would return every employee regardless of department?
1 OR 1=1 -- Resulting query actually executed: -- SELECT * FROM employees WHERE department_id = 1 OR 1=1
Frequently Asked Questions
Does SQL injection only affect SELECT queries?
No, the exact same concatenation mistake in an UPDATE, DELETE, or INSERT statement is just as exploitable, and often far more damaging, an injected DELETE WHERE clause that's always true can wipe an entire table, not just read it.
Is this a flaw in SQL itself, or in how the application uses it?
It's entirely how the application builds the query, SQL has no concept of "trusted" vs "untrusted" text, it just executes whatever string it's handed. The vulnerability lives in the application code that concatenates untrusted input into that string, not in the SQL language or the database engine.
Common Beginner Mistakes
Trying to "sanitize" input by blocking quotes or escaping special characters
This is a real, historically common attempted fix, and it's unreliable, there's almost always some encoding, character, or context the blacklist misses. The actual fix is structural: never concatenate untrusted input into SQL text at all, covered in the next two lessons.
Assuming SQL injection only matters for public-facing web forms
Any input the application doesn't fully control is a risk, an internal admin tool, a CSV import, even a value read from another system, if it ends up concatenated into SQL text, it's exploitable the exact same way.
Best Practices
- Never concatenate untrusted input directly into SQL text, no exceptions, no "just this once."
- Treat every value that didn't originate as a literal written by a developer as untrusted, including data read back from another system.
- Don't rely on blacklisting or escaping specific characters as the actual defense, it's a surface-level patch, not a fix.
Interview Questions
Walk through exactly how a SQL injection attack turns a harmless search box into a full table dump.
If the query is built as "SELECT * FROM employees WHERE last_name = '" + userInput + "'", typing ' OR '1'='1 into the search box produces SELECT * FROM employees WHERE last_name = '' OR '1'='1' once concatenated. '1'='1' evaluates to true for every row, so the WHERE clause stops filtering anything at all, every row in the table comes back, regardless of what was actually searched for.
What's the difference between error-based, union-based, and blind SQL injection?
Error-based and union-based are both "in-band," the attacker sees results directly, either through a revealing error message or by appending a UNION SELECT to pull extra data into the normal output. Blind injection has no visible result or error at all, the attacker infers information indirectly, one true/false condition at a time (boolean-based), or by measuring response delay (time-based), rather than reading anything directly off the page.
Summary
SQL injection happens when untrusted input is concatenated into a query's text instead of kept separate from it, letting that input change what the query actually does, not just what data it searches for. In-band, blind, and out-of-band are the three real categories, differing only in how the attacker observes the result. The fix is structural, never string concatenation, which is exactly what parameters and prepared statements solve.
What's Next?
SQL Parameters is next: the actual mechanism that keeps user input as pure data, never as SQL text, closing this exact vulnerability for good.
Ready to Practice SQL?
Write and run real SQL queries online, right in your browser, no install or signup required. Pick a playground based on which database you want to practice on.
Both open a third-party SQL playground in a new tab. External site terms and privacy policy apply.
Or try 50 SQL practice questions →