What is it?Concept: The application is vulnerable to SQLi but its HTTP response does not contain the results of the relevant SQL query or any database errors. Instead, the attacker extracts data by asking the database a series of YES/NO questions and observe the slight difference in the response to make exploit decision.
A vulnerable application would look like this:
// Vulnerable: Concatenating input into a query where the result isn't displayed, // but it changes the application's behavior (e.g., verifying a tracking cookie or checking if an article exists). String articleId = request.getParameter("id"); String query = "SELECT title FROM articles WHERE id = " + articleId; Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query); if (resultSet.next()) { // If the query returns a result (TRUE), the page loads normally or shows a specific element. out.println("<div>Article loaded successfully!</div>"); } else { // If the query returns nothing (FALSE), the page shows a 404 or hides an element. out.println("<div>Article not found.</div>"); }
How it works
Because the application does not reflect data directly, you must use conditional logic (AND / OR) combined with string extraction functions (like SUBSTRING() or ASCII()). By injecting statements that evaluate to TRUE or FALSE, you observe the change in the web page (content difference, HTTP status code difference, or content length difference, error that appears) to infer the database content character by character.
Step 1: Verify the vulnerability by using a statement that definitely return TRUE or FALSE to test and observe the difference in the output.
5 AND 1=1--5 AND 1=2--
Step 2: Determine the length of the target data (password, table name, column, name…)
5 AND (SELECT LENGTH(password) FROM users WHERE username='admin') =/</> 5--
Step 3: Extract the data character by character using ASCII and SUBSTRING functions.
--Checking if the character at the pos position is an 'a' (ASCII 97)5 AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),pos,1)) = 97--
Mitigation
Fix: Use Prepared Statements
Related Usage
TABLE creation_date AS "Created" FROM "05 - Content" WHERE contains(techniques, this.file.link) AND contains(tags, "🚩") SORT file.name ASC