SQL injection (SQLi) is a vulnerability that lets a malicious hacker introduce (inject) undesired SQL code into SQL queries executed by the software.
Severity: |
![]() ![]() ![]() ![]() ![]() |
very severe |
Prevalence: |
![]() ![]() ![]() |
discovered often |
Scope: |
![]() ![]() ![]() |
may appear in software that uses SQL |
Technical impact: | access to the database or system information | |
Worst-case consequences: | full system compromise | |
Quick fix: | use prepared statements also known as parameterized queries |
If an application uses an external database, it needs to create queries to that database and retrieve results. Most applications use relational databases that support SQL (Structured Query Language). This is a text language designed to be simple and easy to understand by humans. Popular databases supporting SQL include Oracle, Microsoft SQL Server (MSSQL), MySQL, PostgreSQL, and more.
Queries to databases are rarely static – the information that the application needs to get from the database or store in it usually depends on data supplied by the user. User input is typically in the form of simple text, just like SQL syntax itself, so developers often create queries by directly concatenating data supplied by the user with SQL statements. For example, SELECT first_name,last_name FROM users WHERE user_id = '
id_supplied_by_the_user
'
returns the first and last name of the user based on the ID supplied by the user.
If there is no input validation, a malicious hacker may use web page input forms or direct HTTP requests to provide a payload that contains SQL statements. If the application simply concatenates such user data with static commands, the attacker is often able to completely change the syntax and the way the original query works. They may be able to use special characters such as single quotes or semicolons to add commands and/or ignore static commands. The resulting malicious code may even allow the attacker to perform commands such as DROP (deleting a database table or even the entire database). This is called an SQL injection.
SQL injections can happen in any software that communicates with SQL databases. They are most prevalent in web application security because web applications very often use back-end SQL servers. However, they may occur in other types of applications and systems, too.
SQL injections are considered one of the oldest known vulnerabilities – they were first documented in 1998. They are classified as CWE-89: Improper neutralization of special elements used in an SQL command and are included in OWASP Top 10 A3:2021 category (Injection).
Let’s see what an attacker can do with the following simple authentication example:
SELECT * FROM users WHERE user_id = '
id_supplied_by_the_user
' AND password = '
password_supplied_by_the_user
'
This simple SELECT statement returns all relevant user data if there is a matching ID and password record in the database. This means that if the user provides a valid ID and password, the query might return the first and last name of a user (depending on the schema of the users table). If the user provides an invalid ID and/or password, the query returns an empty data set. A developer might use this simple query to check if the user can log in.
A malicious hacker might provide the following id_supplied_by_the_user value:
admin'--
As a result, the query string sent to the database will become:
SELECT * FROM users WHERE user_id = 'admin'--' AND password = ''
The single quote completes the assignment of user_id and the double dash (--) causes the rest of the SQL statement (i.e. the password check) to be treated as a comment. Therefore, the application executes the following query:
SELECT * FROM users WHERE user_id = 'admin'
If executed, this query represents a successful SQL injection. It returns all user data for admin, potentially allowing the malicious hacker to attain unauthorized access to the application as the administrator.
There are 5 primary SQL injection techniques. Each of them is described in detail in a separate section of this guide:
SQL injection is one of the highest severity vulnerabilities for two reasons. First of all, databases accessed by web applications often contain highly sensitive information of top value to attackers. Therefore, attackers are very interested in getting their hands on this data.
Secondly, exploiting SQL injections in combination with other common vulnerabilities can have dramatic consequences. It is even possible to obtain operating system access through an SQL injection, opening the way to a complete system takeover.
Typical consequences of SQL injections include:
If the attacker is able to use privilege escalation (privilege elevation) to obtain operating system access and then root access, they may follow up with any of the following common types of attacks:
The best way to detect SQLi vulnerabilities varies depending on whether they are already known or unknown.
The only fully effective way to prevent SQLi vulnerabilities in web applications is to use parameterized queries (also known as prepared statements) to access SQL databases. Parameterized queries are available in almost every common programming language. They let you avoid string concatenation and instead pass parameters safely to SQL queries. If your programming language does not support parameterized queries but your database engine supports stored procedures, you may use stored procedures with prepared statements instead.
Relying purely on other prevention methods such as whitelists, blacklists, or input filtering/escaping, is not recommended. Malicious hackers may find a way around such sanitization. With the widespread availability of parameterized queries in programming languages and application frameworks, there is no excuse for using custom methods. Such methods may be a fallback only when parameterized queries and stored procedures are not available.
Specific tips on how to use parameterized queries to protect against specific SQLi types are contained in sections dedicated to SQLi types (blind SQL injection, union SQL injection, etc.).
Possible methods to mitigate SQLi attacks will vary depending on the type of vulnerable software:
Classification | ID |
---|---|
CAPEC | 66 |
CWE | 89 |
WASC | 19 |
OWASP 2021 | A3 |
SQL injection (SQLi) vulnerabilities allow malicious hackers to introduce (inject) unexpected SQL code into SQL queries executed by an application. This can let an attacker read data from the database or even modify database contents.
SQL injection is one of the most dangerous vulnerabilities. It is even possible to obtain operating system access through an SQL injection, opening the way to a complete system takeover.
Find out how an attacker can get access to the OS through an SQL injection.
The only fully effective way to prevent SQLi vulnerabilities in web applications is to use parameterized queries (also known as prepared statements) to access SQL databases. Parameterized queries are available in most of the popular programming languages.
Visit Bobby Tables, which contains examples of parameterized queries for many languages.