SQL injection occurs when untrusted input is interpreted as part of a SQL statement rather than as data. The main classes are:
### 1. In-band SQL injection
The attacker sends input and receives results through the same application response.
- **Error-based:** Database errors reveal schema details, query structure, or data.
- **UNION-based:** A manipulated query combines attacker-selected results with the application’s normal result set.
**Developer takeaway:** Don’t expose database errors; use parameterized queries and generic client-facing error messages.
### 2. Blind or inferential SQL injection
The application does not directly return database output, so information is inferred from behavioral differences.
- **Boolean-based:** Responses differ depending on whether an injected condition evaluates true or false.
- **Time-based:** Deliberate database delays allow conditions to be inferred from response timing.
**Developer takeaway:** A lack of visible database errors does not mean an endpoint is safe. Monitor anomalous timing and repeated near-identical requests.
### 3. Out-of-band SQL injection
The database is induced to communicate through another channel, such as DNS or an outbound network request. This is less common and depends on database features and egress access.
**Developer takeaway:** Restrict database-server network egress and disable unnecessary external-access features.
### 4. Stacked-query injection
Input terminates the intended statement and introduces additional statements. Whether this works depends on the database and driver configuration.
**Developer takeaway:** Disable multi-statement execution where possible, but do not treat that as a substitute for parameterization.
### 5. Second-order SQL injection
Malicious-looking input is stored safely at first but later retrieved and concatenated into a new SQL statement, where it becomes executable.
**Developer takeaway:** Treat data read from your own database as untrusted when constructing later queries. Parameterize every query, not only initial inserts.
### 6. Dynamic-SQL injection
Application code, stored procedures, reporting tools, or administrative functions dynamically assemble SQL from strings. Stored procedures are not automatically safe if they concatenate parameters internally.
Common risky areas include:
- Dynamic filtering and search
- Sort columns and directions
- Table or column names
- Bulk import and reporting functions
- ORM “raw query” APIs
**Developer takeaway:** Bind values as parameters. For identifiers that generally cannot be bound, use a strict allowlist mapping user choices to known-safe identifiers.
### 7. Injection in different SQL contexts
Injection is not limited to quoted text fields. It can occur in:
- Numeric expressions
- String values
- `LIKE` patterns
- `ORDER BY`, limits, and offsets
- JSON/XML operators supported by the database
- Full-text search syntax
- Identifier or object-name positions
Escaping rules differ by context, which is why manual quoting is unreliable.
## Core prevention guidance
1. **Use prepared statements or parameterized queries everywhere.**
2. **Avoid string concatenation or interpolation for SQL.**
3. **Allowlist dynamic identifiers and sort options.**
4. **Use least-privilege database accounts**—the application should not own the schema or have administrative rights.
5. **Return generic errors to clients; log detailed errors securely.**
6. **Review stored procedures and ORM escape hatches for dynamic SQL.**
7. **Add automated tests and SAST/DAST checks**, especially for search, filtering, reporting, and administrative endpoints.
8. **Use a WAF only as defense in depth**, not as the primary fix.
9. **Restrict database egress and disable unnecessary capabilities.**
10. **Test both immediate and second-order data flows.**
The simplest message for developers is: **SQL injection is fundamentally a query-construction flaw. Keep SQL code structurally fixed and pass all variable values through the database driver’s parameter-binding mechanism.**