Skip to content

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
Screenshot
Screenshot

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'
Screenshot

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 -- -
Screenshot

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:

  1. Add a condition that is always true (OR 1=1), overriding the category filter
  2. Use -- to comment out everything that follows — including the stray ' and the AND released = 1 condition
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

  1. The category URL parameter was passed unsanitized into a SQL WHERE clause.
  2. Appending ' broke the query and confirmed injectable input.
  3. Injecting ' OR 1=1 -- - closed the string, added an always-true condition, and commented out the released = 1 filter.
  4. 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.