SQL Injection

Attacking databases through malicious input

Introduction

Modern websites and applications rely heavily on databases – When you log into a website, search for a product, view your account information, submit an online form, or make a purchase, there is often a database working behind the scenes.

The application you use – be that an app on your phone, or the web-app in a website – sends queries to that database to retrieve, create, modify, or delete information.

This creates an interesting security boundary. If an application does not properly handle the information supplied by a user, an attacker may be able to manipulate the database query being generated by the application to maliciously interfere with the back-end database.

This type of attack is known as a SQL Injection attack, commonly abbreviated to SQLi.

SQL Injection just one type of a broader type of attacks called code injection attacks, but due to the dominance of SQL as the leading database tool, it has historically been responsible for some extremely serious data breaches.

Depending on the vulnerability and the privileges available to the application, SQL Injection can allow an attacker to access information they should not be able to see, modify or delete database records, bypass authentication, and potentially gain further access to the underlying operating system.

Understanding SQL Injection is therefore an important part of web application and database security.

What is SQL Injection?

SQL Injection is an attack in which an attacker manipulates data supplied to an application so that it changes the SQL query which is executed by the application’s database.

SQL stands for Structured Query Language, and is used by applications to communicate with relational databases such as:

  • MySQL
  • MariaDB
  • Microsoft SQL Server
  • PostgreSQL
  • Oracle Database
  • SQLite

A legitimate application might construct a database query using information supplied by a user. For example, a login application may need to determine whether a supplied username and password correspond to an existing account.

If the application incorporates that information into a SQL statement without safely separating the data from the SQL instructions, specially crafted input may alter the meaning of the query.

The fundamental problem is therefore not simply “bad input”, but rather that the application has allowed untrusted data to influence the structure of a database command.

Why is SQL Injection dangerous?

SQL Injection attacks can have a significant impact because databases frequently contain some of an organisation’s most valuable information.

Depending on the circumstances, an attacker may potentially be able to:

  • Read confidential information
  • Access customer records
  • Obtain usernames and password hashes
  • Access financial information
  • Modify database records
  • Delete information
  • Bypass authentication
  • Access administrative functionality
  • Extract information from multiple database tables
  • Modify application configuration
  • Execute database-specific commands
  • Potentially interact with the underlying operating system

The exact consequences depend on several factors, including:

  • The type of database
  • The application’s database permissions
  • The nature of the vulnerability
  • The application’s architecture
  • Security controls surrounding the database

A SQL Injection vulnerability in a low-privileged application may have a relatively limited impact, but the same vulnerability in an application connected to a highly privileged database account could be catastrophic.

How does SQL Injection work?

A simplified SQL Injection attack involves several stages.

1. The application accepts user input

The application accepts information from a user. This input could come from:

  • A login form
  • A search box
  • A URL parameter
  • A product identifier
  • An API request
  • A cookie
  • An HTTP header

The application uses this information as part of a query command to be presented to the database.

2. The application fails to separate data from commands

The vulnerability occurs when the application constructs a SQL query in an unsafe manner; So, instead of treating the user’s input strictly as data, the database may interpret part of that input as SQL syntax.

This creates the opportunity for injection.

3. The attacker manipulates the input

The attacker supplies specially constructed input designed to alter the behaviour of the database query.

The attacker is not necessarily trying to “break” the database; Instead, they are attempting to make the application ask the database to perform something different from what the developer intended it to do.

4. The database processes the modified query

The database receives the resulting (manipulated) SQL statement, and if the application has failed to protect the query properly, the database may execute the attacker’s injected instructions.

5. The attacker gains unintended functionality or information

Depending on the vulnerability, the attacker may be able to retrieve information, bypass an authentication mechanism, manipulate records, or perform other unauthorised actions.

A simple way to understand SQL Injection

Consider a login prompt – A user is presented with a form on a website that asks for two pieces of authentication data – A username, and a Password

When managed by the SQL interpreter, the data is passed to the database as a query which would say something like “find me the record that matches the account “Peter.Smith” AND where the Password matches “12345ABCDE”

If both of these statements are TRUE, the relevant data is returned. If either of the statements are FALSE, no data is returned.

So what happens if an attacker can trick the SQL interpreter into thinking that the statements are always TRUE?

If an attacker can manipulate the data to say “find me the record that matches the account “Peter.Smith” OR where the Password matches “1=1 –“

The resulting database query now finds a record called “Peter.Smith” and then evaluates the condition 1=1 (which it does, so therefore is TRUE) and then ignores any other commands (the — is a common instruction to comment-out any remaining instructions, and thus ignore them).

As such, even with no provided password, the result of both parts of the statement are TRUE, so data is returned.

Where can SQL Injection occur?

SQL Injection is not restricted to login forms.

Potential injection points include:

  • Search functionality
  • Registration forms
  • Product searches
  • URL parameters
  • API endpoints
  • HTTP headers
  • Cookies
  • Hidden form fields
  • Application filters
  • Reporting systems

Any application component that takes untrusted input and incorporates it into a database query can potentially become an injection point.

Types of SQL Injection

SQL Injection is not a single technique. There are several different categories which an attacker can use to bypass security controls

In-band SQL Injection

In-band SQL Injection occurs when the attacker uses the same communication channel to send the attack and receive the results.

This is one of the easiest forms of SQL Injection to understand because the attacker can directly observe the application’s responses.

Two commonly discussed forms of In-band injection are error-based SQL Injection and UNION-based SQL Injection.

Error-based SQL Injection relies on information revealed through database or application error messages. If an application exposes detailed database errors, those messages may reveal useful information about:

  • Database type
  • Table names
  • Column names
  • Query structure
  • Database configuration

An attacker can potentially use this information to understand the application’s database structure.

Detailed database errors should not normally be exposed to ordinary users.

UNION-based SQL Injection combines the results of compatible queries.

A vulnerable application may allow an attacker to manipulate a query in a way that causes information from another database query to be returned through the application. The attacker may attempt to use this behaviour to retrieve information from tables that the original application functionality was never intended to expose.

Blind SQL Injection

Blind SQL Injection occurs when the application does not directly return useful database information. The attacker instead has to infer what is happening based on how the application behaves.

For example, the application might produce different responses depending on whether a particular database condition is true or false. The attacker can then use these behavioural differences to infer information.

Blind SQL Injection can be considerably slower than attacks where database information is directly returned.

Time-based SQL Injection

Time-based SQL Injection is a form of blind SQL Injection. Instead of relying on visible differences in the response, the attacker attempts to determine whether a database condition is true based on whether the application takes noticeably longer to respond.

Repeated observations can potentially reveal information about the underlying database.

SQL Injection and data theft

Databases often contain sensitive information such as:

  • Customer names
  • Email addresses
  • Telephone numbers
  • Password hashes
  • Financial records
  • Order information
  • Employee information
  • Internal application data

A successful SQL Injection vulnerability may allow an attacker to retrieve information outside the intended functionality of the application. The scale of the potential breach depends heavily on the privileges assigned to the application’s database account.

This is why least privilege is an important defence against SQL Injection.

SQL Injection and data manipulation

SQL is not only used to retrieve information, it can also be used to create, modify, and delete database records.

Consequently, a SQL Injection vulnerability can potentially allow an attacker to manipulate application data such as:

  • Account information
  • Product prices
  • User permissions
  • Transaction records
  • Application settings
  • Customer information

This means SQL Injection can impact on both confidentiality and integrity.

SQL Injection and database privileges

One of the most important factors determining the impact of SQL Injection is the account used by the application to connect to its database.

Consider two applications.

Application A connects using an account that can only read one specific database, access only the tables it requires, and perform only limitedoperations

Application B connects using a highly privileged database account with broad access, and capability.

If both applications contain the same SQL Injection vulnerability, the potential impact could be dramatically different.

This demonstrates an important security principle, in that A vulnerability should be contained by limiting the privileges available to the vulnerable component.

This is called the principle of least privilege.

SQL Injection beyond web applications

Although SQL Injection is commonly associated with websites, the underlying problem can occur anywhere software dynamically constructs SQL queries using untrusted data.

Potentially vulnerable systems can include:

  • Mobile applications
  • Desktop applications
  • Internal business applications
  • APIs
  • Enterprise software
  • Reporting systems
  • Database administration interfaces

The vulnerability is therefore fundamentally an application development problem, rather than simply a website problem.

Why do SQL Injection vulnerabilities happen?

Several development practices can contribute to SQL Injection:

  • Concatenating user input into SQL – This is one of the most common causes of attack and works by constructing SQL statements by directly combining strings and user-supplied information. This makes it difficult for the application to distinguish between SQL instructions and user data.
  • Poor input handling – Applications may fail to properly restrict the type and format of information they accept. For example, an application expecting a numerical identifier may accept arbitrary text.
  • Lack of parameterised queries – Applications that do not use parameterised queries or prepared statements may be more vulnerable to injection. If an application only allows data to be presented to the database as part of a pre-designed template, it becomes much harder to change the data presented into a malicious statement
  • Excessive database privileges – Even if an application is compromised, excessive database privileges can dramatically increase the potential impact.
  • Poor error handling – Detailed database errors can reveal information that helps attackers understand the application’s internal structure which can lead to other attacks.

How can organisations prevent SQL Injection?

The most effective defence is to ensure that untrusted input can never change the structure of a SQL query.

  • Parameterised queries, also known as prepared statements, separate SQL commands from user-supplied data. This means that input is treated as data rather than being interpreted as SQL instructions. Parameterised queries are one of the most important protections against SQL Injection.
  • Input validation – Applications should validate ALL information before processing it. So data should be examined for, expected data type, expected length, allowed characters, valid ranges, expected file formats. For example, if an application expects a numerical identifier, it should validate that the supplied value is actually a valid number, and not text.
  • Least privilege – All Database accounts should have only the permissions required for the application to operate. An application that only needs to read particular tables should not automatically receive unrestricted access to the entire database.
  • Secure error handling – Applications should not expose detailed database errors to users. Instead, the application should provide a generic error message while recording useful diagnostic information securely in server-side logs.
  • Web Application Firewalls (WAF) – These can inspect incoming web traffic and attempt to identify malicious requests. However, a WAF should not be treated as a replacement for secure application development, the underlying application should still use parameterised queries and other secure coding practices.
  • Security testing – Organisations should regularly test applications for SQL Injection vulnerabilities. Identifying vulnerabilities during development is considerably safer than discovering them after an application has been deployed.

Detecting SQL Injection attacks

Security teams can look for unusual database and application behaviour.

Potential indicators include:

  • Unusual database errors
  • Unexpected changes in SQL query patterns
  • Large numbers of malformed requests
  • Repeated requests containing suspicious input
  • Unexpected database access
  • Unusual data extraction
  • Authentication anomalies
  • Unexpected changes to database records
  • Unusual application response times

Web server logs, application logs, database logs, WAF logs, and security monitoring platforms can all contribute to detection.

Logging is particularly important

An organisation cannot investigate an attack effectively if there is no useful evidence showing what happened. Security teams should consider logging things like:

  • Source IP addresses
  • Request paths
  • Authentication events
  • Application errors
  • Database errors
  • Administrative actions
  • Significant database activity

Care must be taken not to log sensitive information such as passwords or other secrets.

SQL Injection in the modern threat landscape

SQL Injection has existed for many years, yet it remains relevant.

Modern development frameworks and security practices have significantly reduced the number of vulnerable applications, but poorly designed applications, legacy software, custom-developed systems, and incorrectly implemented database interactions can still introduce vulnerabilities.

The continued use of large databases also means that the potential consequences remain significant.

A SQL Injection vulnerability in an application connected to a database containing millions of records can create a substantial security risk.

SQL Injection and modern APIs

Modern applications increasingly communicate through APIs rather than traditional web pages.

An API might accept information such as:

  • User IDs
  • Search terms
  • Product IDs
  • Account numbers
  • Filters
  • Sorting parameters

If that information is subsequently incorporated into SQL queries without appropriate protections, the API can become an injection point.

API connections often run with much higher data throughput than traditional webpage connections, so the volume at which an API-based SQL attack can take place can be magnitudes larger than one preformed via a webpage.

This demonstrates why SQL Injection should not be viewed purely as a problem affecting traditional HTML forms.

Modern application architectures still need strong database security controls.

SQL Injection prevention checklist

Organisations developing applications should consider the following:

  • Never trust user input.
  • Use parameterised queries.
  • Use prepared statements.
  • Never trust user input.
  • Validate input according to expected types and formats.
  • Apply least privilege to database accounts.
  • Avoid unnecessary database permissions.
  • Never trust user input.
  • Protect database servers from direct Internet exposure.
  • Prevent detailed database errors from being displayed to users.
  • Keep application frameworks and database software updated.
  • Never trust user input.
  • Implement secure coding practices.
  • Conduct regular security testing.
  • Monitor application and database activity.
  • Deploy a WAF where appropriate.
  • Maintain effective logging and incident response capabilities.
  • Never trust user input.

Conclusion

SQL Injection is a powerful example of how seemingly simple application design decisions can create serious security vulnerabilities.

If an application fails to properly separate user-supplied data from SQL instructions, it can allow an attacker to manipulate the queries sent to a database, and, depending on the vulnerability and the privileges available to the application, can potentially allow attackers to access confidential information, bypass authentication, manipulate records, delete data, and potentially gain further access to systems.

Security depends on maintaining a clear boundary between trusted instructions and untrusted data.

When that boundary fails, information supplied by a user can become a mechanism for controlling the system itself.