SQL injection, also known as SQLi, SQLI or SQL*, is a cyber attack that exploits vulnerabilities in an application’s database queries by inserting malicious SQL code into user input fields.
SQL injection attacks often result in the attacker retrieving data from a database, modifying data in a database or gaining access to the underlying server running a database.
What Is SQL Injection?
SQL injection is a type of cyber attack that allows attackers to insert and execute malicious SQL code through an application's input fields, potentially gaining unauthorized access to or control over the database.
How Do SQL Injection Attacks Work?
SQL injection attacks involve an attacker directly inserting malicious SQL code into user-input variables, such as username or password fields, on websites or variables in API calls, which are then executed against the SQL database.
Attackers can exploit this vulnerability when user input is inserted directly into SQL queries without validation or sanitization. This means the attacker is able to execute any SQL code they wish by adding it into the user-input field and, as long as it results in a valid SQL query, the database will treat it as valid and execute it.
Types of SQL Injection
1. In-Band SQL Injections
In-band SQL injection attacks occur when an attacker is able to use the same call or communication mechanism to both perform the attack and gain the results.
This usually means the SQL attack is passed as an API call and the results of the injected query are returned in the response. It may also occur, however, by triggering an error and having the results return as part of the error.
2. Inferential SQL Injections
Inferential SQL injections are when an attacker is able to perform the injection but unable to see the results of the query directly.
Typically, this type of attack requires a lot more work and effort on the attacker’s part to get meaningful data. Attackers usually make use of boolean conditions or time-based delays to produce an observable outcome.
With boolean conditions, the attacker can guarantee the presence or lack of results from the response to determine if the injection performed or found anything meaningful. With time-based delays, the attacker injects SQL commands that cause the database to pause execution for a specific amount of time. If the delay occurs, the attacker infers that the condition was true; if not, it was false.
3. Out-of-Band Injections
Out-of-band SQL injection attacks are when the attacker is either unable to use the same call or communication mechanism to both perform the attack and gain the results, or uses a feature or mechanism of the database to send the data over another mechanism (saving results to a file, the database sending the results over a different network call, etc.).
SQL Injection Examples
Imagine a website’s user login page that asks for a username and password. Once the user has submitted the information, the web server takes this information and checks if the details provided match a legitimate entry in its SQL database.
The web server does this by taking the information provided by the user and placing it into an SQL query, like so:
SELECT * FROM users WHERE username = '<USERNAME>' AND password = '<PASSWORD>';
If the query returns a value, then the user is considered legitimate and they’re allowed to log in. However, this login system is vulnerable to SQL injection because it directly incorporates user input into the query without validation or parameterization.
Example 1
Now, imagine an attacker gave these values:
username: 'admin' OR 1=1--
password: --
This would construct a query such as:
SELECT * FROM users WHERE username = 'admin' OR 1=1--' AND password = '--';
In this case, a result would be returned as long as there’s a row in the database with the username of admin, or if 1 is equal to 1, which is always true, so the attacker would be able to log in.
The rest of the query would not be executed, because the attacker placed a comment to prevent the rest of the query from being used. As a note, if the attacker changed the OR to AND, the query would only succeed if both the username and password matched a valid set of credentials — so it wouldn’t bypass authentication unless the attacker already knew the correct values.
Example 2
Finally, consider what would happen if an attacker were to provide these values:
username: 'admin' OR 1=1--; DROP TABLE users; --
password: --
This would result in an SQL query that looks like:
SELECT * FROM users WHERE username = 'admin' OR 1=1--; DROP TABLE users; -- AND password = '--';
In this case, the attacker chains multiple SQL statements. If the server allows multiple queries in a single call — which is uncommon but possible in misconfigured environments — this would not only bypass authentication but also delete the entire users table. Most modern systems disable multi-statement execution by default for this reason.
How to Prevent SQL Injection Attacks
User Prepared Statements
You can prevent most SQL injection attacks by using prepared statements (also known as parameterized queries), instead of directly placing user input into the query.
By using this coding style, the database distinguishes between what is intended to be SQL code and what is intended to be data regardless of whatever the user has supplied. This helps ensure that even if an attacker were to provide a value that contains valid SQL code, the database would treat it simply as user data and not allow it to modify or affect the query in any way.
Escape User Supplied Input
A less effective way of preventing SQL injection attacks is to escape user supplied input, particularly input that has a special meaning in SQL such as: *, ‘, --, ; etc.
Escaping means using a special character, typically \, to inform the database that the character should be treated as part of the data and not a modification of the query.
While this technique can prevent some SQL injection, it won’t prevent all SQL injection attacks. There are potential workarounds and bypasses, and it’s extremely database specific.
Common Security Best Practices
Do Not Trust User-Supplied Data
If your service receives data or input from sources outside of your control, such as user-supplied information, be sure to not place inherent trust in the authenticity of the data. Be careful not to immediately process or use the data without sanitizing or formatting it, or in some way confirming it matches the expected format and contains nothing disallowed.
Do Not Return Errors As-Is
If your service encounters an error during an operation, ensure that it doesn’t return the error message as-is back to the user. Otherwise, the error message may leak information an attacker could find useful, such as the type of database used, query used, data returned in a query, etc.
When an error does occur, send the user a generic error message that doesn’t provide the specifics of the error.
Frequently Asked Questions
What is SQL injection?
SQL injection is a type of cyber attack and code injection technique that allows an attacker to insert malicious SQL statements into an application’s input fields, enabling unauthorized access, data modification or control over a SQL database.
What are the main types of SQL injection attacks?
The three main types of SQL injection attacks are:
- In-band, where the attacker uses the same communication channel to send the attack and receive results.
- Inferential, where the attacker infers results based on application behavior without directly seeing query outputs.
- Out-of-band, where the attacker retrieves data through a separate communication channel or database feature.
How can developers prevent SQL injection attacks?
The most effective method for preventing SQL injection attacks is using prepared statements, which separate SQL code from user input. This prevents input from being interpreted as code. Escaping input characters is another technique, but it can be less reliable and highly database-specific.
