SQL Injection: The Complete Practical Guide

SQL Injection in Unexpected Contexts

SQLi beyond the WHERE clause: ORDER BY and identifiers that cannot be parameterized, LIMIT/OFFSET, HTTP headers, JSON bodies, and ORM raw escapes, step by step.

Published

Most tutorials show injection in a WHERE clause, so that is where people look. Real applications put user input into plenty of other parts of a query, and several of them cannot be fixed with a bound parameter at all. These contexts are where injection survives after the easy spots are patched.

Injecting in ORDER BY

You cannot bind an identifier, so a sortable column is frequently concatenated straight in:

?sort=name       -> ORDER BY name
?sort=name;...    -> the value lands in the ORDER BY

There is no string to close here, so quote-based payloads do not apply. Confirm and exploit with a conditional expression instead:

?sort=(CASE WHEN (1=1) THEN name ELSE email END)        (changes the ordering if true)
?sort=(SELECT CASE WHEN (condition) THEN 1 ELSE 1/0 END) (errors or delays on true)

You can also probe by column index: ?sort=1 versus ?sort=2 reorders results if the value is used positionally.

LIMIT and OFFSET

Pagination parameters often reach LIMIT n OFFSET m unparameterized. Depending on the DBMS you can append a subquery or, on MySQL, a PROCEDURE ANALYSE-style trick, and time-based conditions work well here because the clause accepts expressions.

Column and table identifiers

Anywhere the app lets you choose a field to display, filter, or group by, the identifier may be concatenated. These must be fixed with an allow-list, never a quote escape, which is exactly why they stay vulnerable.

HTTP headers logged to the database

Applications log request metadata, and that insert is often built by concatenation:

User-Agent: ' OR (SELECT ... )-- -
X-Forwarded-For: ', (SELECT ...))-- -

If a User-Agent, X-Forwarded-For, Referer, or cookie is written to an analytics or audit table, the header is your injection point. This frequently becomes second-order injection when an admin later views the logs.

JSON and nested parameters

Modern APIs take JSON. Values deep inside the body still reach queries, so inject into nested fields, array elements, and keys, not just top-level params:

{ "filter": { "status": "active' OR 1=1-- -" } }

ORM raw escapes

ORMs are safe until someone reaches for the raw hatch: raw(), whereRaw(), extra(), string interpolation inside a query builder, or a hand-built fragment for something the ORM cannot express. Those fragments concatenate input like any other, so audit every raw call.

Hunt the non-obvious inputs on a free live target, then read WAF and filter evasion for when a filter stands in the way.

← Back to SQL Injection: The Complete Practical Guide