SQL Injection Attacks (SQLi)

What are SQL injection attacks, and how can you prevent them?

At a Glance:

Structured Query Language (SQL) is a language designed to manipulate and manage data in a database. Since its inception, SQL has steadily found its way into many commercial and open source databases. SQL injection (SQLi) is a type of cybersecurity attack that targets these databases, using specifically crafted SQL statements to trick the systems into doing unexpected and undesired things.

Actions a successful attacker may take on a compromised target include: bypassing authentication, exfiltrating/stealing data, modifying or corrupting data, deleting data, running arbitrary code, or gaining root access to the system itself.

Databases are commonly targeted for injection through an application (such as a website, which requests user input and then does a lookup in a database based on that input), but they can also be targeted directly. SQL injection attacks are listed on the OWASP Top Ten list of application security risks that companies are wrestling with.

Types of SQL Injection Attacks

SQL injection attacks can be carried out in a number of ways. Attackers may observe a system’s behavior before selecting a particular attack vector/method.

Unsanitized Input

Unsanitized input is a common type of SQLi attack in which the attacker provides user input that isn’t properly sanitized for characters that should be escaped, and/or the input isn’t validated to be the type that is correct/expected. 

For example, a website used to pay bills online might request the user’s account number in a web form and then send that to the database to pull up the associated account information. If the web application is building a SQL query string dynamically with the account number the user provided, it might look something like this:

            “SELECT * FROM customers WHERE account = ‘“ + userProvidedAccountNumber +”’;”

While this works for users who are properly entering their account number, it leaves the door open for attackers. For example, if someone decided to provide an account number of “‘ or ‘1’ = ‘1”, that would result in a query string of:

            “SELECT * FROM customers WHERE account = ‘’ or ‘1’ = ‘1’;”

Due to the ‘1’ = ‘1’ always evaluating to TRUE, sending this statement to the database will result in the data for all customers being returned instead of just a single customer.

Blind SQL Injection

Also referred to as Inferential SQL Injection, a Blind SQL injection attack doesn’t reveal data directly from the database being targeted. Rather, the attacker closely examines indirect clues in behavior. Details within HTTP responses, blank web pages for certain user input, and how long it takes the database to respond to certain user input are all things that can be clues depending on the goal of the attacker. They could also point to another SQLi attack avenue for the attacker to try.

Out-of-Band Injection

This attack is bit more complex and may be used by an attacker when they cannot achieve their goal in a single, direct query-response attack. Typically, an attacker will craft SQL statements which, when presented to the database, will trigger the database system to create a connection to an external server the attacker controls. In this fashion, the attacker can harvest data or potentially control behavior of the database.

A Second Order Injection is a type of Out-of-Band Injection attack. In this case, the attacker will provide an SQL injection that will get stored and executed by a separate behavior of the database system. When the secondary system behavior occurs (it could be something like a time-based job or something triggered by other typical admin or user use of the database) and the attacker’s SQL injection is executed, that’s when the “reach out” to a system the attacker controls happens.

How to Prevent SQL Injection Attacks

The following suggestions can help prevent an SQL injection attack from succeeding:

Don’t use dynamic SQL

Sanitize user-provided inputs

  • Properly escape those characters which should be escaped.
  • Verify that the type of data submitted matches the type expected.

Don’t leave sensitive data in plaintext

  • Encrypt private/confidential data being stored in the database.
  • This also provides another level of protection just in case an attacker successfully exfiltrates sensitive data.

Limit database permissions and privileges

  • Set the capabilities of the database user to the bare minimum required.
  • This will limit what an attacker can do if they manage to gain access.

Avoid displaying database errors directly to the user

  • Attackers can use these error messages to gain information about the database.

Use a Web Application Firewall (WAF) for web applications that access databases

  • This provides protection to web-facing applications.
  • It can help identify SQL injection attempts.
  • Based on the setup, it can also help prevent SQL injection attempts from reaching the application (and, therefore, the database).

Use a web application security testing solution to routinely test web apps that interact with databases

  • Doing so can help catch new bugs or regressions that could allow SQL injection.

Keep databases updated to the latest available patches

  • This prevents attackers from exploiting known weaknesses/bugs present in older versions.

SQL injection is a popular attack method for adversaries, but by taking the proper precautions such as ensuring data is encrypted, that you protect and test your web applications, and that you’re up to date with patches, you can take meaningful steps toward keeping your data secure.