Using a Structured Query Language (SQL) statement, a database administrator or developer can query, manipulate and manage data stored in a database. Databases are an essential backend used to support interactive web applications. SQL is in common use in both commercial and open-source software, making it a common means of attack. A SQL injection (SQLi) is a type of data injection attack in which an attacker inserts SQL statements into an input field used in an existing query to alter the request for their purposes, often to access sensitive information beyond the scope of the intended functionality. A successful SQL injection attack can result in any of the following:
A successful SQL injection attack has the potential to cause serious financial and reputational harm to an organization due to its ability to expose sensitive corporate assets, financial information, or user information.. The Open Web Application Security Project (OWASP) lists SQL injection on its Top 10 list of application security risks, which has remained true since the list was first created, due to its frequency and the significance of its abuse.
Security analysts classify SQLi attacks into categories that include unsanitized input, blind SQLi and out-of-band SQLi.
An attacker performing an SQLi attack may provide unsanitized data, meaning the database hasn’t checked the data to ensure that it’s valid. This type of attack works by causing the database to behave in ways that benefit the attacker. Assume for this example that a web application builds a query to provide the user with account information. A user who provides 123456 as the account number causes the web server to generate the following query:
SELECT * FROM customers WHERE account = “123456”;
However, an attacker can enter the string “or ‘1’ == ‘1’” to generate the query
“SELECT * FROM customers WHERE account = “or ‘1’ == ‘1’”;
The condition ‘1’ == ‘1’ always evaluates to TRUE, so this query will provide the attacker with the account data for all users. Since one of the OR clauses in this statement is always true, the value in the account field is irrelevant. Every customer record will therefore meet the criteria specified by the SQL statement.
Blind SQLi attacks don’t directly provide the attacker with data from the targeted database. Instead, these attacks provide clues about the database’s behavior that the attacker can use to conduct a future attack. Common sources of information in a blind SQLi attack include blank web pages, HTTP responses, and the database’s response time.
An example of a blind SQLi attack is to enter the string “ ‘ or sleep(10)” for the password field. If this attack succeeds, it will delay all responses from the server for 10 seconds.
Attackers typically use an out-of-band SQLi when a direct query-response fails their goal. One method consists of submitting an SQL statement that creates a connection between the target database and a server the attacker controls. The attacker can then use this connection to collect data or otherwise control the database’s behavior. Like unsanitized inputs, this type of SQLi attack usually relies on the database not properly validating user inputs.
This example of an out-of-band SQLi uses two tables named Contacts and Users:
The Contacts table has the following fields:
Meanwhile the Users table includes:
Users log in to the database by entering their user name and password on a login page. The web server uses this information to construct a query that looks like the following:
select EmployeeID from Users where username=’jdoe1’ and password=’P@$$w0rd’;
The web server then executes this query, which returns the EmployeeID of the user with the user name of “jdoe1” and password is “P@$$w0rd”. Database servers typically return a status code as well to indicate that the query returned a result. If it did, the webserver logs the user into the database.
An attacker in an out-of-band SQLi attack can exploit the authentication process by submitting a password of “x’ or 1==1” resulting in the query:
Select EmployeeID from Users where username=’jdoe1’ and password=’x’ or 1==1;
In this case, the condition 1==1 is always true, so the web application authenticates the login attempt to jdoe1 even though the attacker didn’t provide the correct password for that account.
It may also be possible to obtain user data similarly, provided the web page can display data. In addition to the “‘x’ or 1==1” clause, the attacker can add a string like “UNION SELECT LastName, credit card number, security code from Contacts” to the password field. If the web application fails to validate the password data and executes the resulting query, it will return every user’s last name, credit card number, and security code.
There are two primary components to ensuring that your database is protected against SQL Injection attacks: enforce input validation and use prepared statements.
The application must never use user-supplied input directly. Any data pulled from a user-supplied field without doing proper input-validation could result in a SQL Injection vulnerability. Software developers need to ensure all application inputs are sanitized; this includes not just data from forms, but any data source used for logging or application logic such as User-Agent or Referrer headers.
Prepared statements, also known as parameterized queries, allow an application to safely use user-supplied input by explicitly declaring that data as elements of a larger query, rather than being a piece of the query itself. Providing a layer of indirection in the query prevents a malicious input from overriding the original programmatic intent of the request sent to the database.
Inputs containing potential SQL query elements, such as single quotes, should be examined and removed as necessary. Verbose error messaging should also be disabled as these can be used with injection attacks to gain additional useful information about the database structure. Additionally, enforcing security hygiene through consistent enforcement of the Least Privilege Principle to ensure database software is run with the minimum privileges essential for database operation, removing unused default tables, reviewing asset configurations as part of periodic maintenance efforts, and regular penetration testing, will help to identify any potential issues before they arise.
Additional layers of protection could include use of a Web Application Firewall as part of a defense-in-depth strategy. However, this can not be recommended as a sole line of defense. If a determined adversary were to discover an evasion for the filtering rules in use, no additional defenses would exist to prevent further abuse.