Hi, below you may find a short instructions how to detect SQL injections at your application.
Let’s analyze a basic HTTP request:
POST /user?profile=7 HTTP/1.1
Host: example.co.uk
...
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
first_name=Oliver
1. Where to Look
SQL Injection often hides in GET
and POST
parameters (e.g., profile=7
, first_name=Oliver
), but it may also exist in headers like User-Agent
or Cookie
.
2. Numeric Fields (e.g., profile=7
)
Try injecting basic arithmetic:
profile=8-1
profile=3+4
profile=12/2
If the responses match that of profile=7
, it suggests the backend directly evaluates expressions within SQL. To confirm, add SQL-specific syntax:
profile=8-(SELECT 1 FROM DUAL)
If the response remains consistent, the parameter is likely vulnerable.
3. Text Fields (e.g., first_name=Oliver
)
Start with a quote to escape the value:
first_name=Oliver'
If the system returns an error, it’s likely vulnerable. Try controlled concatenation:
first_name=Oli'||'ver
first_name=Oli'||(SELECT 'v' FROM dual)||'er
first_name=Oli'||(SELxyzECT 'v' FROM dual)||'er // malformed
If the first two behave normally and the malformed version errors out, that’s a strong sign of injection risk. Safer alternative to OR 1=1:
first_name=Oliver' AND 1=1
first_name=Oliver' AND 1=2
Compare output — if they differ, you’ve likely found a flaw. If queries are wrapped in parentheses, you may need to match them:
first_name=Oliver') AND 1=1
first_name=Oliver')) AND 1=1
4. Sortable Columns (e.g., sort=first_name
)
SELECT … ORDER BY first_name. Try:
sort=first_name
sort=first_name/**/
sort=first_name,1
sort=first_name,(SELECT 1)
sort=first_name_unknown
If all but the last work identically, the input is likely used directly in the query — a red flag.
5. Mapped Parameters (e.g., user[town]=Brighton
)
Some apps use structured parameters mapped to column names:
user[town]=Brighton&user[email]=oliver@localmail.uk
Which may become:
SELECT ... WHERE town='Brighton' AND email='oliver@localmail.uk'
Try subtle changes like:
user[town/**/]=Brighton
If the app behaves the same, it’s likely vulnerable. Test a full injection:
user[town%3Dtown AND 1=2--]=x
Compare to:
user[town%3Dtown AND 1=1--]=x
If the second returns results while the first does not — SQL Injection confirmed.
If you would like to get real practice at SQL injection vulnerabilities and how to prevent them – then welcome to my Udemy course: “PHP REST API cybersecurity“