Expert · Web attacks and their fixes · topic 21 of 35 · 22 min
SQL injection (SQLi)
Explanation
The flaw in one picture
A web app often builds a database query using something the user typed, such as a username. If the app glues the input directly into the query text, a clever input can change what the query does. That is SQL injection (SQLi): the user's input is treated as part of the SQL code.
Imagine a login query built like this (the unsafe way):
query = "SELECT * FROM users WHERE name = '" + input + "'"
# If input is: ' OR '1'='1
# the query becomes:
SELECT * FROM users WHERE name = '' OR '1'='1'
# '1'='1' is always true, so it may return every user and log the attacker in.How a tester finds it (in a lab)
A tester puts a single quote or similar into a field and watches for a database error or a change in behaviour. In DVWA at the "low" level, this is the first thing you try. The point is not to steal data; it is to prove the input reaches the query unsafely, then write it up.
The fix: parameterised queries
The real fix is to never build query text from input. Instead, use parameterised queries (also called prepared statements): the query has placeholders, and the input is sent separately as data. The database then treats the input as a value, never as code, so no input can change the query's meaning.
// Unsafe:
db.query("SELECT * FROM users WHERE name = '" + name + "'");
// Safe: a placeholder, with the value passed separately
db.query('SELECT * FROM users WHERE name = ?', [name]);Detection and defence
- Fix (primary): parameterised queries / prepared statements everywhere.
- Defence in depth: validate input types, give the database account least privilege, and never show raw database errors to users.
- Detection: database errors in logs, odd characters in inputs, and a web application firewall (WAF) flagging injection patterns.
- An ORM (a library that builds queries for you) uses parameters by default — but only if you avoid its raw-query escape hatches.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
SQL injection (SQLi) · 1/7
SQL injection: user input is treated as part of the database query.
Prefer a video by a teacher? Find free videos on “sql injection explained and prevention parameterised queries” on YouTube ↗
In real life: A login bypass in the lab
On DVWA set to "low", a learner types ' OR '1'='1 into the username box and is logged in without a valid password. He records it as a critical SQL injection finding. Then he switches DVWA to "high", reads the source, and sees it uses a prepared statement; the same input now fails harmlessly. He writes the fix in one line: "use parameterised queries so input is never part of the SQL". Attack and defence, learned together.
Practice (0/3 done)
SQL injection happens when…
The primary fix for SQL injection is…
As a simple detector for a lab log, write looks_like_sqli(value) that returns True if the input contains a single quote (') or the text "--" or " OR " (case-insensitive), else False.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Cross-site scripting (XSS)Web attacks and their fixes · same module
- CSRF and IDORWeb attacks and their fixes · same module
- SSRF and authentication flawsWeb attacks and their fixes · same module
- SQL injection and how to stop itBackend Development · Backend security
- SQL injection and safe queriesJava Programming (Core to Spring Boot) · JDBC, Maven, Gradle and JUnit
- The OWASP Top 10 with fixesCyber Security: from zero to SOC analyst · Malware and web security
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Why does ' OR '1'='1 often work in a vulnerable login?
Answer: It makes the WHERE condition always true
'1'='1' is always true, so the condition passes.
Parameterised queries protect you because input is…
Answer: Treated only as data, never as SQL code
The database treats placeholders' values as pure data.
Showing raw database errors to users is risky because…
Answer: It hands attackers clues about the query and schema
Detailed errors help an attacker refine the injection.
An ORM helps prevent SQLi because it…
Answer: Uses parameters by default (if you avoid raw queries)
ORMs parameterise queries unless you use their raw escape hatch.
What causes SQL injection?Related
Answer: Joining user input directly into SQL text
When user text is glued into the query, it can change the query itself. That is injection.
What is the main fix for SQL injection in Java?Related
Answer: PreparedStatement with parameters
Parameters are the correct default.
Which is the correct fix for SQL injection?Related
Answer: Parameterised queries
Parameterised queries keep data separate from the SQL code.
Stored XSS differs from reflected XSS because it…Related
Answer: Is saved on the server and shown to many viewers
Stored XSS persists and affects every viewer of the page.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 3 more topics in “Web attacks and their fixes” before its exam: Cross-site scripting (XSS), CSRF and IDOR, SSRF and authentication flaws.
- Module 7 exam: web attacks and fixes · 13 questions · 22 min, without help. 4 topics of this module still to finish first.
- Then the next module, Deeper lab skills: passwords, privilege, Metasploit, wireless. 35 topics left in the course before the final exam.