SQL Injection

Severity: High
Test name: SQL Injection (SQLI)

An SQL injection attack involves the unauthorized insertion of a malicious SQL query into an application through client-provided input data. This allows attackers to perform any SQL query on the client's database under the application's permissions, enabling them to read, modify, or delete sensitive information or even execute administrative operations on the server.

Key varieties of SQL injection attacks include:

  • Blind Boolean Based: Here, the attacker sends SQL queries that prompt the database to answer with TRUE or FALSE, deciphering data based on the application's responses.
  • Blind Time Based: This method involves sending SQL queries that cause intentional delays in the database's response and using these delays to extract sensitive data for further assaults.
  • Union Based: This approach utilizes the UNION SQL operator to merge the outcomes of two or more SELECT queries into a single result, which is then returned in the application's response.
  • Database Error in Response: Attackers can glean sensitive details about the database's structure through the error messages provided by triggering database server errors.

This vulnerability allows an attacker to:

  • Modify application data
  • Bypass protection mechanism
  • Read application data
Example of the Union Based injection
  1. The unprotected application executes the following query containing the user input Laptops:
SELECT name, price FROM products WHERE category = 'Laptops'
  1. Instead of Laptops, an attacker can submit the input like ' UNION SELECT login, password FROM users--.
  2. As a result, the application will return all usernames and passwords along with the names and descriptions of the products. The following SQL will be executed:
SELECT name, price FROM products WHERE category = '' UNION SELECT login, password FROM users--

The issue can be found in the source code on the server side.

Remedy suggestions
  • Use the prepared statements with variable binding (aka parameterized queries). Parameterized queries force the developer first to define all the SQL code, and then pass each parameter (given below) to the query later. This coding style allows the database to distinguish between code and data, regardless of the user's input type.
    • Java EE – use PreparedStatement() with bind variables
    • .NET – use parameterized queries like SqlCommand() or OleDbCommand() with bind variables
    • PHP – use PDO with strongly typed parameterized queries (using bindParam())
    • Hibernate - use createQuery() with bind variables (called named parameters in Hibernate)
    • SQLite - use sqlite3_prepare() to create a statement object
  • Avoid the generation of dynamic SQL inside stored procedures. If it can't be avoided, the stored procedure must use input validation or proper escaping to ensure that all user-supplied input to the stored procedure can't be used to inject SQL code into the dynamically generated query.
  • Use the least privilege approach to provide in-depth defense and minimize the potential damage of a successful SQL injection attack. Minimize the privileges assigned to every database account in your environment (do not assign DBA or admin-type access rights to your application accounts).
  • CWE-89
  • CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N