Skip to content

Expert · Web attacks and their fixes · topic 21 of 35 · 22 min

SQL injection (SQLi)

Explanation

SQL injection happens when user input is put straight into a database query, so the input can change the query's meaning. The fix is always the same idea: never mix user input into query text; use parameterised queries so input is treated as data, not code.

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):

output
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.
Unsafe string-building lets input change the query. This is the bug, not a tool to use elsewhere.
Think of it like this: Think of a form where the clerk reads your answer out loud as an instruction. You write in the "name" blank: "Asha. Also, give me the whole register." A careless clerk obeys the extra instruction. A careful clerk treats everything you wrote as just a name. Parameterised queries make the database the careful clerk.

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.

javascript
// 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]);
The ? is a placeholder; the value in the array is treated only as data. This is the fix.

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.
Careful: This section teaches SQLi so you can find and fix it on authorised targets. Never test injection against a system you do not own or have permission to test; it is unauthorised access and, if it causes damage, far worse under the IT Act.

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

Input becomes code

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)

Task 1 · Question

SQL injection happens when…

Task 2 · Question

The primary fix for SQL injection is…

Task 3 · Code · Python

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

Question 1

1.Why does ' OR '1'='1 often work in a vulnerable login?

Question 2

2.Parameterised queries protect you because input is…

Question 3

3.Showing raw database errors to users is risky because…

Question 4

4.An ORM helps prevent SQLi because it…

Read more (free)

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.

From SQL injection and how to stop it

What is the main fix for SQL injection in Java?Related

Answer: PreparedStatement with parameters

Parameters are the correct default.

From SQL injection and safe queries

Which is the correct fix for SQL injection?Related

Answer: Parameterised queries

Parameterised queries keep data separate from the SQL code.

From The OWASP Top 10 with fixes

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.

From Cross-site scripting (XSS)

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

  1. 3 more topics in “Web attacks and their fixes” before its exam: Cross-site scripting (XSS), CSRF and IDOR, SSRF and authentication flaws.
  2. Module 7 exam: web attacks and fixes · 13 questions · 22 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Deeper lab skills: passwords, privilege, Metasploit, wireless. 35 topics left in the course before the final exam.

← Previous: The OWASP approach to web testing