Injection Points
While most SQLi occurs in WHERE clauses, vulnerabilities can appear anywhere in a query:| Location | Example |
|---|---|
| UPDATE | Updated values or WHERE clause |
| INSERT | Inserted values |
| SELECT | Table/column name, ORDER BY clause |
Attack Types
- Retrieving hidden data — modify a query to return additional results
- Subverting application logic — alter query behavior to bypass checks
- UNION attacks — pull data from other tables
- Blind SQLi — exploit queries whose results aren’t directly returned
Example: Retrieving Hidden Data
Original request and query:OR 1=1 makes the WHERE clause always true; -- discards the trailing conditions. Result: all products returned, including unreleased ones.
Subverting Application Logic
A typical login query:administrator'-- as the username (with a blank password), the query becomes:
-- comments out the password check entirely, so the attacker logs in as administrator with no password required.
Retrieving Data from Other Tables
Using the UNION keyword, an attacker can append a second SELECT to an existing query and pull data from entirely different tables. Original query:' UNION SELECT username, password FROM users-- produces:
Blind SQL Injection
With blind SQLi, the application doesn’t return query results or error details — but the vulnerability can still be exploited. Techniques include:- Boolean-based — inject a condition that changes the app’s response depending on whether it’s true or false (e.g. injecting into Boolean logic or triggering a divide-by-zero error)
- Time-based — conditionally trigger a time delay; infer truth from how long the app takes to respond
- Out-of-band (OAST) — trigger an external network interaction (e.g. a DNS lookup to a domain you control) to exfiltrate data directly; useful when other techniques fail
Second-Order SQL Injection
First-order SQLi is straightforward — user input from an HTTP request is immediately incorporated into a SQL query unsafely. Second-order (aka stored) SQLi is more subtle: the application stores the user input safely at first, but later retrieves it and incorporates it into a query unsafely. The vulnerability isn’t at the point of storage — it triggers on a completely different HTTP request down the line.
Examining the Database
SQL behaves differently across platforms — techniques that work on MySQL may not work on Oracle. Key differences include syntax for string concatenation, comments, batched queries, platform-specific APIs, and error messages. Once a vulnerability is confirmed, fingerprinting the database helps tailor the attack. Two useful starting points: Version detection (result reveals DB type):SQL Injection in Different Contexts
SQLi isn’t limited to query strings — any input processed as SQL is a potential vector, including JSON and XML bodies. These formats can also help bypass WAFs: filters that block keywords likeSELECT can often be evaded by encoding or escaping characters. For example, encoding the S in SELECT as an XML escape sequence:
S back to S before passing it to the SQL interpreter — bypassing the filter while executing normally.
How to Prevent SQL Injection
The fix for most SQLi is parameterized queries (aka prepared statements) — never concatenate user input directly into a query. Vulnerable:- Whitelisting permitted input values
- Different logic to deliver the required behavior
Examining the Database
Querying Version & Type
Inject provider-specific version queries to fingerprint the database:| Database | Query |
|---|---|
| Microsoft, MySQL | SELECT @@version |
| Oracle | SELECT * FROM v$version |
| PostgreSQL | SELECT version() |
Listing Database Contents
Queryinformation_schema.tables to list all tables:
information_schema.columns:
information_schema — use these equivalents instead: