Validate SQL injection vulnerabilities (including blind SQLi) across time-based, error-based, boolean-based, UNION-based, stacked-query, and out-of-band patterns. Use when testing CWE-89 (SQL Injection), CWE-564 (Hibernate SQL Injection), and related SQL injection classes across MySQL, PostgreSQL, MSSQL, Oracle, and SQLite targets.
Validate SQL injection (including blind SQLi) by injecting SQL syntax into user-controlled inputs and observing:
Inject time-delay functions and detect response latency.
Detection Methods: SLEEP(5), pg_sleep(5), WAITFOR DELAY '0:0:5', heavy functions (e.g., randomblob() for SQLite).
Inject true/false conditions and compare content/length/status.
Detection Methods: ' OR '1'='1 vs ' OR '1'='2, AND 1=1 vs AND 1=2.
Trigger SQL parser errors and observe verbose error responses.
Detection Methods: stray quote/backtick, type-cast errors, extractvalue()/updatexml() (MySQL), CAST('a' AS INT) (PostgreSQL/MSSQL).
Use UNION to extract data when column counts align.
Detection Methods: UNION SELECT NULL,NULL, ORDER BY N probing for column count.
Inject additional statements when DB/driver permits (e.g., MSSQL ; WAITFOR, PostgreSQL ; SELECT pg_sleep(5)).
Detect DNS/HTTP callbacks via load_file(), xp_dirtree, or UTL_HTTP/UTL_INADDR when response-based detection is blocked (use only if callback infra is authorized).
Hibernate/JPA or query-builder misuse leading to SQLi (parameter concatenation, unsafe createQuery).
| Database | Time-Based | Error-Based | Boolean-Based | UNION | Stacked Queries |
|---|---|---|---|---|---|
| MySQL/MariaDB | SLEEP(5) | ✓ | ✓ | ✓ | Limited |
| PostgreSQL | pg_sleep(5) | ✓ | ✓ | ✓ | ✓ (; SELECT ...) |
| MSSQL | WAITFOR DELAY '0:0:5' | ✓ | ✓ | ✓ | ✓ |
| Oracle | dbms_pipe.receive_message | ✓ | ✓ | ✓ | Limited |
| SQLite | No native sleep; use heavy ops (randomblob) | ✓ | ✓ | Partial | No |
Time-Based (Blind):
payload = "123' OR SLEEP(5)--"
resp_time = send(payload)
if resp_time > baseline_time + 4.5:
status = "VALIDATED"
Boolean-Based (Blind):
true_p = "123' OR '1'='1"
false_p = "123' OR '1'='2"
len_true = len(send(true_p).text)
len_false = len(send(false_p).text)
if abs(len_true - len_false) >= 50:
status = "VALIDATED"
Error-Based:
payload = "123'"
resp = send(payload)
if any(err in resp.text.lower() for err in sql_errors):
status = "VALIDATED"
UNION/Stacked Probing:
ORDER BY incrementally to find column count.UNION SELECT NULL,... until count matches; watch for 200 vs 500.; SELECT pg_sleep(5) or ; WAITFOR DELAY '0:0:5'.Out-of-Band (only if infra-approved):
| Status | Meaning |
|---|---|
| VALIDATED | Clear SQLi indicators (delay, error, boolean diff, data via UNION/stacked, OOB hit) |
| FALSE_POSITIVE | No indicators; behavior unchanged |
| PARTIAL | Mixed/weak signals (small deltas, inconsistent responses) |
| UNVALIDATED | Blocked, error, or insufficient evidence |
Capture minimal structured evidence (redact PII/secrets, truncate to 8KB, hash full response). Include:
status, injection_type, cweValidated examples:
Time-based SQLi on /api/users?id - SLEEP(5) payload caused 5.1s delay (CWE-89). Evidence: path/to/evidence.json
Boolean-based SQLi on /products - response length differs for true vs false condition (CWE-89). Evidence: path/to/evidence.json
Error-based SQLi on /login - SQL syntax error returned to client (CWE-89). Evidence: path/to/evidence.json
Unvalidated example:
SQLi test incomplete on /reports - WAF blocked payloads (403). Evidence: path/to/evidence.json
Primary CWEs (DAST-testable):
Parent/Related CWEs (context):
Note: CWE-89 is ranked #2 in MITRE's 2025 CWE Top 25 Most Dangerous Software Weaknesses.
reference/sql_payloads.py for SQLi payloads by DB and detection type.reference/validate_sqli.py for a SQLi-focused validation flow (time/error/boolean/UNION/stacked).examples.md for concrete SQLi scenarios and evidence formats.