SQL injection Cheat Sheet

SQL injection (SQLi) refers to a critical web security flaw enabling malicious actors to manipulate an application’s database queries

Impacts and Risks of SQL Injection Attacks

By exploiting this vulnerability, attackers gain unauthorized access to data beyond their normal privileges. This may encompass sensitive information of other users or any data accessible to the application. Additionally, attackers can tamper with, delete, or alter data, leading to lasting modifications in the application’s content and behavior.

Extended Consequences and Historical Incidents

In certain scenarios, SQL injection can be leveraged to advance the attack and compromise the underlying server or other back-end systems, potentially leading to a denial-of-service attack. The consequences of a successful SQL injection attack are profound. Unauthorized access to critical information, like passwords, credit card details, and personal user data, can occur. Numerous well-known data breaches have been attributed to SQL injection attacks, causing severe reputational harm and substantial regulatory penalties. Moreover, attackers might establish a persistent backdoor in an organization’s systems, leading to a long-lasting compromise that remains undetected for an extended period.

How to Detect SQL Injection Vulnerabilities

Detecting SQL injection vulnerabilities is crucial for ensuring the security of web applications and databases. It’s essential to use a combination of manual and automated techniques for comprehensive SQL injection vulnerability detection. Automated tools can efficiently scan large applications, while manual analysis allows for a deeper understanding of the context and potential edge cases. Regular and proactive vulnerability assessments are essential to maintain the security of web applications and protect against evolving threats.

Manual Detection Techniques

  • Input Validation Review the application’s code to ensure that all user inputs are appropriately validated and sanitized before being used in SQL queries. Check for proper encoding and escaping of user-supplied data.
  • Testing Special Characters Manually input special characters, such as single quotes, double quotes, semicolons, and SQL operators, into input fields to see if they cause any unexpected behavior or errors.
  • Error Messages Observe error messages returned by the application. If they disclose SQL-related errors or stack traces, attackers might use this information to exploit the vulnerability.
  • URL Manipulation Alter URL parameters, form fields, or hidden inputs to check for SQL injection possibilities. Observe the application’s response to any unexpected behavior.
  • Union-Based Queries Attempt to inject SQL code that utilizes the “UNION” keyword to combine results from different database queries. If the application’s response includes data from unrelated tables, it could indicate a SQL injection vulnerability.
  • Time-Based Attacks Inject SQL queries that cause time delays in the application’s response. If the response time varies significantly based on the injection, it may indicate a time-based blind SQL injection vulnerability.

Automated Detection Techniques

  • Web Application Scanners Use specialized web application security scanners like OWASP ZAP, Burp Suite, or Acunetix to automatically crawl through the application, identifying potential vulnerabilities, including SQL injection.
  • Static Code Analysis Tools Utilize static code analysis tools to examine the application’s source code and identify patterns that might indicate SQL injection vulnerabilities.
  • Dynamic Analysis Employ dynamic analysis tools that interact with the web application like a user, injecting malicious inputs to test for SQL injection vulnerabilities.
  • Database Security Scanners Some tools focus specifically on scanning databases for potential SQL injection vulnerabilities, testing various types of injections, and query manipulations.
  • Cloud-based Security Services Cloud-based security services may provide automated scanning and monitoring of web applications for potential vulnerabilities, including SQL injection.

SQL Injection Examples

1. Subverting Application Logic This refers to exploiting vulnerabilities in an application’s SQL implementation to gain unauthorized access or manipulate data in unintended ways. Consider the following code:

-- Application code (PHP example)

$username = $_POST['username'];

$password = $_POST['password'];

$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";

The above code expects the username and password as input, and it constructs an SQL query using those inputs. However, an attacker can exploit this by inputting a specially crafted string as the username and password. The resulting SQL query would look like this:

SELECT * FROM users WHERE username='' OR '1'='1' AND password='...'

The condition ‘1’=’1′ always evaluates to true, which means the query will return all rows from the “users” table, effectively bypassing the login process.

2. Accessing Data From Other Database Tables When a SQL query’s results are included in an application’s responses, an attacker can exploit a SQL injection vulnerability to access data from other tables in the database. This is accomplished by utilizing the UNION keyword, which enables the execution of an extra SELECT query, and then merging its results with the original query’s output. As an illustration, suppose an application runs the subsequent query involving user input, “Cakes”: SELECT name, description FROM products WHERE category = ‘Cakes’

In such a scenario, a malicious attacker could submit the input: ‘ UNION SELECT username, password FROM users–.  Consequently, this action will lead the application to provide not only all usernames and passwords but also names and descriptions of products.

3. Blind SQL Injection Vulnerabilities This occurs when an application is susceptible to SQL injection, but it does not directly expose the results of injected SQL queries. Attackers must rely on the application’s behavior to infer whether their injected statements are true or false.

One type of blind SQL injection is Boolean-based, where attackers inject conditions that evaluate to true or false. For instance, they might append ‘ OR 1=1; — to an input field, causing the query to always return true, revealing information that should be restricted.

Another form of blind SQL injection is time-based, where attackers introduce delays in the query to observe differences in the application’s response time. By using database-specific functions, like pg_sleep() or BENCHMARK(), attackers can gauge the truth of their injected conditions based on the response delay.

Blind SQL injection attacks can be more time-consuming for attackers, but they can still lead to unauthorized data extraction or actions on the database.

4. Retrieving Hidden Data Retrieving hidden data in a database using SQL involves exploiting a vulnerability that allows unauthorized access to restricted information. One common method is by using conditional statements such as released = 1 and released = 0.

Assume there is a table called “products” with a column named “released” that indicates whether a product is publicly available (released) or not (hidden or restricted). The value 1 represents products that are released, and 0 represents products that are not yet released (hidden or restricted). If the application does not properly validate user input or has weak access controls, an attacker could craft a malicious SQL query to access hidden data.

For example: To retrieve released products (value = 1): SELECT * FROM products WHERE released = 1; To retrieve hidden (unreleased) products (value = 0): SELECT * FROM products WHERE released = 0;. An attacker could inject these queries or modify existing ones to gain access to products they shouldn’t see based on their permissions.

Essential Syntax for SQL Injection

This SQL injection cheat sheet contains examples of useful syntax that you can use to perform a variety of tasks that often arise when performing SQL injection attacks.

1. Comments By employing comments, you can truncate a query and eliminate the portion of the original query that comes after your input.

PostgreSQL --comment

/*comment*/

MySQL #comment

-- comment [Note the space after the double dash]

/*comment*/

Microsoft --comment

/*comment*/

2. Substring You can extract a portion of a string starting from a specified offset and with a specified length. Remember that the offset index is 1-based. Each of the following expressions will yield the string “tech.”

PostgreSQL SUBSTRING('comparitech', 8, 3)

MySQL SUBSTRING('comparitech', 8, 3)

Oracle SUBSTR('comparitech’, 8, 3)

Microsoft SUBSTRING('comparitech', 8, 3)

3. String concatenation You can combine multiple strings to form a unified string.

PostgreSQL 'compari'||'tech’

MySQL 'compari' 'tech' [Note the space between the two strings]

CONCAT('compari','tech')

Oracle 'compari'||'tech'

Microsoft 'compari'+'tech'

4. Database version You can execute a database query to identify its type and version. This data becomes valuable when devising more intricate attack strategies.

PostgreSQL SELECT version()

MySQL SELECT @@version

Oracle SELECT * FROM v$version

SELECT version FROM v$instance

Microsoft SELECT @@version

5. Database contents You can retrieve a list of tables existing in the database and the corresponding columns contained within each table.

PostgreSQL SELECT * FROM information_schema.tables

SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'

MySQL SELECT * FROM information_schema.tables

SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'

Oracle SELECT * FROM all_tables

SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE'

Microsoft SELECT * FROM information_schema.tables

SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'

6. Conditional errors By evaluating a single boolean condition, you can induce a database error when the condition holds.

MySQL SELECT IF(YOUR-CONDITION-HERE,(SELECT table_name FROM       

information_schema.tables),'a')

Oracle SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN TO_CHAR(1/0) ELSE  

NULL END FROM dual

Microsoft SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 1/0 ELSE NULL END

PostgreSQL

1 = (SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 1/(SELECT 0) ELSE NULL END)

7. Extracting data via visible error messages By crafting a malicious query, you can potentially provoke error messages that inadvertently expose sensitive data.

PostgreSQL SELECT CAST((SELECT password FROM users LIMIT 1) AS int)

> invalid input syntax for integer: "secret"

MySQL SELECT 'foo' WHERE 1=1 AND EXTRACTVALUE(1, CONCAT(0x5c, (SELECT 'secret')))

> XPATH syntax error: '\secret'

Microsoft SELECT 'foo' WHERE 1 = (SELECT 'secret')

SELECT 'foo' WHERE 1 = (SELECT 'secret')

> Conversion failed when converting the varchar value 'secret' to data type int.

8. Batched (or stacked) queries Batched queries allow you to execute multiple queries in sequence. However, it’s essential to remember that the results are not directly returned to the application. This method is particularly valuable when dealing with blind vulnerabilities, where you can utilize a second query to initiate DNS lookups, trigger conditional errors, or introduce time delays for further inference.

PostgreSQL QUERY-1-HERE; QUERY-2-HERE

MySQL QUERY-1-HERE; QUERY-2-HERE

Oracle Does not support batched queries.

Microsoft QUERY-1-HERE; QUERY-2-HERE

How to Prevent SQL Injection Vulnerabilities

To prevent SQL injection vulnerabilities, follow these best practices while writing code:

1. Use Parameterized Statements (Prepared Statements) Parameterized statements separate the SQL query logic from the user input data, preventing the mixing of data and code. Here’s an example in PHP using PDO (PHP Data Objects):

// Unsafe way (vulnerable to SQL injection)

$username = $_POST['username'];

$password = $_POST['password'];

$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";

// Safe way (using prepared statements)

$stmt = $pdo->prepare("SELECT * FROM users WHERE username=:username AND password=:password");

$stmt->execute(array(':username' => $_POST['username'], ':password' => $_POST['password']));

2. Input Validation and Sanitization Validate and sanitize user inputs to ensure they conform to expected formats. Use whitelisting and blacklisting as appropriate.

// Example of input validation and sanitization in PHP

$userId = $_GET['id'];

if (is_numeric($userId)) {

    // Valid user ID, proceed with the query

} else {

    // Invalid input, handle appropriately (e.g., show an error message)

}

3. Escaping User Inputs When direct embedding of user input into queries is unavoidable, escape the data to neutralize potential SQL injection attacks. However, using parameterized statements is generally safer.

// Escaping user input in PHP

$username = mysqli_real_escape_string($conn, $_POST['username']);

$password = mysqli_real_escape_string($conn, $_POST['password']);

$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";

4. Least Privilege Principle Ensure that database users have the minimum required privileges, limiting their access to only what’s necessary for their tasks.

5. Stored Procedures Opt for utilizing stored procedures with suitable parameters when interacting with the database, rather than employing inline SQL queries. This approach aids in centralizing query logic and fortifying defenses against SQL injection attacks.

-- Example of a stored procedure in MySQL

DELIMITER //

CREATE PROCEDURE GetUserByUsername(IN username VARCHAR(50))

BEGIN

    SELECT * FROM users WHERE username = username;

END //

DELIMITER ;

6. ORMs (Object-Relational Mapping) You may want to consider utilizing ORM libraries that provide a layer of abstraction over database interactions, minimizing the chance of direct SQL injection vulnerabilities. Keep in mind that a holistic security strategy involves combining these measures along with frequent security audits to safeguard against emerging threats and ensure the utmost protection for your web applications and databases.

Furthermore, it is also important to consult the OWASP documentation for further reference. OWASP offers an extensive SQL Injection Prevention Cheat Sheet, which effectively addresses the above issues, mitigating SQL Injection vulnerabilities. These techniques are adaptable and can be implemented with almost any programming language and database type.