Sql Injection (SQLi)
Types of SQL Injection
In-band
Error-based
Queries are sent that cause the application to output SQL error messages.
Information about the database can be learned from these error messages.
Union-based
UNION SQL queries are used to grab information from the database.
The results are returned in the application’s normal HTTP responses.
Blind
Boolean-based
A SQL query is sent that contains a condition causing the server to respond differently depending on whether the condition is true or false.
By observing response differences, data can be inferred bit by bit.
Time-based
SQL queries are used that cause the server to delay its response by a predictable amount of time.
SQL injection is confirmed if the server responds with the expected delay.
Out-of-band
Output of the SQL injection is exfiltrated through an outbound communication channel (e.g. HTTP or DNS) from the SQL server.
Useful when in-band or time-based techniques are not feasible.
Second-order
The malicious SQL payload is stored in the database and later used by a different query.
Example: create a user on a website with a name that is actually a SQL injection payload, then view that user in a context where the name is used in a vulnerable query.
Preventing SQL Injection
Prepared statements (parameterized queries)
SQL queries are turned into prepared statements and user input is bound to parameters.
User input cannot be used to change the structure or intent of the SQL query.
Stored procedures
Similar to prepared statements, except the parameterized SQL queries are stored in the database itself.
Dynamic SQL inside stored procedures (string concatenation) can still introduce SQL injection vulnerabilities.
Object-Relational Mapping (ORM)
Interact with the SQL database using a programming language instead of raw SQL queries.
ORMs typically use parameterized queries behind the scenes.
They can still be insecure if concatenated SQL strings are used.
Validate and transform user input to strong types (integer, boolean, date, etc.) before using it in queries.
Reject or normalize unexpected input rather than passing it directly to SQL.
Escape user input before placing it in a query when parameterization is not possible.
Escaping rules are database-specific.
Proper escaping helps ensure user input is not interpreted as part of the SQL statement.
Limit maximum input length.
Whitelist characters: only allow characters that are required.
Blacklist characters or patterns where appropriate (e.g. control characters, certain operators), but do not rely on blacklists alone.
Least privilege
Assign the database account the lowest privilege possible to limit impact if compromised.
Where possible, give applications access only to stored procedures, not direct table access.
Run the database service under a low-privilege OS account.
Web Application Firewall (WAF)
Detects and filters known SQL injection signatures and patterns.
Uses a constantly updated ruleset to block common attacks.
Error handling
Do not display detailed database or stack trace errors on the webpage.
Log detailed errors server-side and show only generic error messages to users.