How to Prevent SQL Injection Attacks?[7 Best Practices]
Are you aware of the increasing threat of SQL injection vulnerabilities?
In early 2024, AppTrana blocked over 10 million attacks in just three months, highlighting the intense siege on web applications.
How can you prevent SQL injection attacks? Techniques like input validation, restricting database user privileges, and using parameterized queries are essential.
This blog offers a guide to understanding SQL injection vulnerabilities and details essential techniques to protect your applications.
What are Databases and SQL?
A database is a collection of tables where data is stored and accessed. SQL, or Structured Query Language, communicates with and manipulates this data. SQL commands include “SELECT,” “UPDATE,” “INSERT,” “DELETE,” “CREATE,” and “DROP.”
What is SQL Injection?
SQL injection is a type of cyber attack where an attacker inserts or manipulates malicious SQL queries into an application’s input fields to gain unauthorized access to a database, manipulate data, or execute other harmful commands.
This attack exploits vulnerabilities in how the application processes user inputs, allowing the attacker to interact with the database in unintended ways.
SQL injection attacks are classified as ‘high impact severity’ by OWASP Top 10 due to their serious threat to data security. Developers must safeguard their code to prevent unauthorized access and data breaches.
What Causes SQL Injection?
SQL injection typically results from failing to properly sanitize user input. If an application accepts user input in SQL statements without proper validation, attackers can inject malicious SQL queries.
For instance, attackers could use SQL injection to bypass login systems by crafting queries that always return true, allowing unauthorized access. They might also modify data, steal sensitive information, or perform other harmful actions.
Attackers may use information from SQL error messages to refine their techniques and exploit vulnerabilities more effectively.
How does SQL Injection Work?
Here’s a simple example of how SQL injection works:
Imagine a website with a SQL database for storing user information. The website has a login form where users enter their username and password. The website’s code might look like this:
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0)
{
// User has successfully logged in
}
else
{
// Invalid username or password
}
In this code, the user’s input is directly inserted into the SQL statement. If an attacker enters a username like admin’ –, the SQL statement becomes:
SELECT * FROM users WHERE username=’admin’–‘ AND password=”
The double dash (–) is a comment character in SQL, which means everything after it is ignored. This allows the attacker to bypass the password check and log in as the administrator.
Attackers often try different variations of SQL injection commands to see which ones are executed by the database. They may continue exploiting these vulnerabilities to access sensitive information or perform malicious actions until the security issues are resolved.
Types of SQL Injection Attacks
SQL injection attacks come in various types, each with its own characteristics. Here’s a rundown of the most common types of SQLi attacks:
- Error-Based SQL Injection
- Union-Based SQL Injection
- Blind SQL Injection
- Time-Based Blind SQL Injection
- Boolean-Based Blind SQL Injection
1. Error-Based SQL Injection
Error-based SQL injection involves sending malicious SQL queries to trigger errors or confirm vulnerabilities in the application. Attackers use these errors to gather information about the database structure or other sensitive details.
How to detect Error based SQL Injection?
Attackers may use SQL commands like single quotes, double quotes, or operators such as AND, OR, and NOT to provoke errors.
For example, entering http://demo.testfire.net/index.php?title=1′ might generate an error message like:
“You have an error in your SQL syntax; check the manual corresponding to your MySQL server version for the right syntax to use near ‘‘VALUE’’.
The error message gives him vital information like:
- DB used as MySQL
- Error in the syntax is a double quote
- The place of the error caused is at the end of the parameter
2. Union-based SQL Injection
In this type of SQL Injection, attackers try to exploit the vulnerability with the help of the “UNION” operator.
The UNION operator is used for combining 2 tables or performing 2 select queries simultaneously. In union operators, they remove duplicate rows or columns, which we try to execute simultaneously.
Union-based SQL Injection Example:
Suppose a web application builds an SQL query like this:
SELECT name, email, phone FROM users WHERE name = '[user_input]'
The user input is not properly sanitized, so an attacker could inject their own SQL code. For example, they could enter the following value as their name:
' UNION SELECT password, NULL, NULL FROM users --
This would result in the following SQL query being executed:
SELECT name, email, phone FROM users WHERE name = '' UNION SELECT password, NULL, NULL FROM users --'
The — at the end of the injected string is a comment symbol, which comments out the rest of the original query. So, the resulting query would be equivalent to:
SELECT name, email, phone FROM users WHERE name = ''
UNION SELECT password, NULL, NULL FROM users
This query would return a table with the user’s name, email, and phone number and a table with all the passwords in the user table. The attacker could then use this information to further compromise the system.
3. Blind SQL Injection
Blind SQL injection occurs when attackers cannot see the actual database content but infer information based on the application’s responses.
There are two main types of blind SQL injection attacks:
1. Boolean-based SQLi
2. Time-based SQLi
1. Boolean-based SQLi
In this type of SQL Injection attack, the attacker sends a series of SQL queries that evaluate either true or false, depending on whether the injected code was executed successfully.
The attacker can then use the application’s response to infer information about the database by constructing complex queries that probe for specific information.
Boolean-based SQLi Example: Deleting a user database using Boolean-based SQLi
How it works: A common online shop’s SQL database query could be like this:
SELECT ItemName, ItemDescription FROM Item WHERE ItemNumber = ItemNumber
So, a product URL on the online store could be
http://www.exampleshop.com/items/items.asp?itemid=999 or 1=1.
The SQL query could be
SELECT ItemName, ItemDescription FROM Items WHERE ItemNumber = 999 OR 1=1
One is always equal to one. It’s just a basic mathematical fact that holds true no matter where you are. SQL queries return all product names and descriptions in the database, even those you lack permission to access.
2. Time-based SQLi
This attack involves injecting a query that is designed to cause a delay in the application’s response. By measuring the time, it takes for the application to respond to the query, the attacker can determine whether the query was successful.
This technique is helpful when the attacker has no answer (error/output) from the application because the input validation has been sanitized.
Time-based SQL injection example
For example, let’s say there is a login form on a web application that uses a SQL query to check whether a user’s credentials are valid. The query might look something like this:
SELECT * FROM users WHERE username = 'admin' AND password = 'password123'
To perform a blind SQLi attack, an attacker could inject a query like this:
SELECT CASE WHEN (1=1) THEN pg_sleep(10) ELSE pg_sleep(0) END;
This query will cause the application to sleep for 10 seconds if the condition “1=1” is true. The attacker can determine whether the condition was true or false by measuring the time it takes for the application to respond to this query.
If the response takes 10 seconds, the attacker knows that the condition was true and that the application is vulnerable to blind SQLi. If the response is immediate, the attacker knows the condition was false.
Once the attacker has confirmed that blind SQLi is possible, they can start injecting more complex queries to extract sensitive information from the database.
To prevent blind SQL injection, ensure that all user inputs are properly sanitized and validated. Use parameterized queries or prepared statements to separate SQL logic from data, minimizing the risk of injection attacks. Additionally, implement robust error handling to avoid revealing sensitive information through error messages.
How Are SQL Injections Bot-Driven?
SQL injection attacks can be automated using bots, which can scale the attacks and make them more dangerous. Here’s how bots can drive SQL injection attacks:
- Automated Attack Execution: Bots can be programmed to automatically send SQL injection payloads to web applications. They can test various input fields and attempt different types of injections at high speeds, which would be difficult for a human to achieve manually.
- Scalability: Bots can execute thousands of SQL injection attempts simultaneously across multiple websites or applications. This scalability increases the likelihood of finding a vulnerability and makes it harder for organizations to defend against such attacks.
- Advanced Techniques: Bots can use advanced techniques to evade detection, such as rotating IP addresses, using proxies, and employing encryption. They can also employ sophisticated SQL payloads designed to bypass common security measures.
- Data Harvesting: Once a bot successfully injects malicious SQL code, it can automate the process of extracting sensitive data from the database. The data at risk may encompass usernames, passwords, credit card numbers, or other private information.
- Continuous Exploitation: Bots can continuously probe for vulnerabilities and exploit them over time. They can also adapt to changes in the application’s structure or security measures, making them persistent threats.
To combat bot-driven SQL injection attacks, implement rate limiting to control request volumes from single IPs and block malicious IPs. Additionally, use bot detection tools like CAPTCHA and behavioral analysis to identify and mitigate bot traffic.
Impacts of Injection Attacks
SQL injection attacks can have extensive and damaging effects, varying based on the target. Key impacts include:
- Data Theft: Attackers can extract sensitive information such as usernames, passwords, credit card numbers, and personal details from a database.
- Data Modification or Deletion: Unauthorized manipulation or deletion of data can lead to significant data loss or damage, affecting the integrity and reliability of the information.
- System Takeover: By gaining administrative access, attackers can control systems, leading to further malicious activities like additional attacks, malware installation, or unauthorized changes.
- Financial Loss: The costs of SQL injection attacks can be substantial, including direct expenses for system restoration and data recovery, as well as indirect losses from disrupted business operations and lost revenue.
- Regulatory and Legal Consequences: Businesses may face financial penalties or legal action due to data breaches, particularly those handling sensitive information, such as financial institutions or healthcare providers.
- Reputation Damage: A successful attack can severely damage a company’s reputation, leading to long-term harm to future growth and profitability.
- Operational Disruption: Downtime caused by attacks can result in lost revenue and customer frustration, further impacting the business’s reputation.
Additionally, attackers often combine SQL injection with other tactics like insufficient authentication, DNS hijacking, XSS, and DDoS attacks, which can exacerbate the financial damage and lead to more severe system compromises.
Most Notorious SQLi Attacks in History
The following are some of the most famous SQL attacks in recent years that every company must be aware of:
Kotak Life Insurance Data Breach 2023: The fastest-growing insurance company encountered a targeted data breach that exploited a SQL injection zero-day vulnerability within the MOVEit application. The BBC has reported that multiple organizations in the UK, including the BBC itself, have confirmed instances of data breaches resulting from a MOVEit transfer SQL injection vulnerability.
WooCommerce unauthenticated SQL Injection: In July 2021, WooCommerce disclosed that several of its feature plug-ins and software versions were vulnerable to SQL injections; they noticed several security attacks occurring during that time.
Kaseye ransomware attack: In July 2021, a notorious group called REvil affected over 1500 businesses managed by Kaseya. Hacker remotely exploited the SQL vulnerability of the Kaseya VSA servers.
Drupal SQL Injection: On October 2014, Drupal declared its high vulnerability against the attack. Lack of user input sanitization resulted in SQL injection vulnerability. Drupal core versions ranging from 7.0 to 7.31 were vulnerable.
The Target Data Breach: In 2013, the Target Corporation was the victim of a massive data breach that affected 40 million customers. Experts claim that the server fell to SQL injection attacks.
Yahoo Hack: In July 2012, 453,000 email addresses and passwords of Yahoo Voices users were leaked. The credentials were stored in an unencrypted way. Hackers have stolen the data by executing a SQL Injection attack.
The Sony PlayStation Network Hack: In 2011, the Sony PlayStation Network (PSN) was hacked, resulting in the loss of personal information for 77 million users. The hack was reportedly the result of a SQL injection attack. The attackers were able to gain access to sensitive information such as users’ names, addresses, and credit card numbers.
How to Prevent SQL Injection Attacks?
To effectively prevent SQL injection attacks, securing all inputs and server-side processes is essential. While client-side validation helps, it is not sufficient against determined attackers. Here’s a comprehensive approach to prevent and mitigate SQL injection attacks, featuring 7 key mitigation techniques:
7 Effective Techniques to Prevent SQL Injection Attacks
- Implement Input Validation and Sanitization
- Use Escaping for User Input
- Utilize Parameterized Statements (Prepared Statements)
- Incorporate Stored Procedures
- Conduct Continuous Scanning and Penetration Testing
- Adopt the Least Privilege Principle
- Deploy Web Application Firewalls (WAF)
1. Implement Input Validation and Sanitization
By validating and sanitizing user input, applications can ensure that only expected data formats and types are accepted, thereby mitigating the risk of malicious SQL commands being injected into SQL queries.
Input validation involves verifying that user input remains to predefined criteria, such as format, length, and range, while sanitization involves removing or encoding potentially harmful characters from the input.
Whether dealing with SQL injection, XSS, Command Injection or other injection vulnerabilities, input validation ensures that user inputs adhere to expected formats while sanitization removes potentially harmful elements.
Example (using PHP and filter_var):
$username = filter_var($_POST['username'], FILTER_SANITIZE_STRING);
2. Use Escaping for User Input
This SQL injection mitigation technique involves modifying user inputs to neutralize special characters that could be used for malicious SQL injection.
The database system interprets these characters as literal values rather than executable code by escaping them. Using database-specific escape functions or libraries is crucial to handling special characters properly.
Example (using PHP and MySQLi):
In PHP, the mysqli_real_escape_string function can be utilized to escape user inputs before incorporating them into SQL queries:
$user_input = mysqli_real_escape_string($connection, $_POST['user_input']);
$password_input = mysqli_real_escape_string($connection, $_POST['password_input']);
$query = "SELECT * FROM users WHERE username = '$user_input' AND password = '$password_input'";
Key Considerations – Use Database-Specific Escaping Functions
Different database systems may have unique escaping functions. Always use the appropriate escaping functions provided by the specific database being used (e.g., mysqli_real_escape_string for MySQL, pg_escape_string for PostgreSQL).
3. Utilize Parameterized Statements (Prepared Statements)
Another effective coding practice to mitigate the risk of SQL injection is parameterized statements. Parameterized statements separate user inputs from the SQL query, eliminating the need for manual escaping.
This ensures that user inputs are treated as data, preventing the execution of malicious code. The database system recognizes placeholders and binds user inputs securely during execution.
Example (using Python and SQLite):
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (user_input, password_input))
Instead of directly embedding user inputs into the SQL query, placeholders (?) are used for the values that will be provided later.
The execute method of the database cursor is used to execute the SQL query. The first argument is the SQL query with placeholders, and the second argument is a tuple containing the actual values (user_input and password_input) that will replace the placeholders.
The database system recognizes the placeholders (?) and binds the user inputs securely during execution. This means that the values provided in the tuple are treated as data, not as part of the SQL query, preventing any potential SQL injection.
4. Incorporate Stored Procedures
Stored procedures encapsulate SQL code within the database. The injection risk is minimized by defining parameterized procedures, as these procedures are executed without directly incorporating user inputs.
Example (using SQL Server):
CREATE PROCEDURE GetUser
@username NVARCHAR(50)
AS
BEGIN
SELECT * FROM users WHERE username = @username;
END
Despite popular belief, relying on stored procedures doesn’t offer complete or direct defense for a system against SQL injection. Like SQL queries directly integrated into an application, stored procedures remain vulnerable to malicious injection if not managed carefully.
To prevent SQL injection in stored procedures, it is crucial to parameterize the queries within the procedure rather than concatenating parameters directly.
Example (Incorrect Method in MySQL) – Concatenating parameters directly
CREATE PROCEDURE GetUser(IN username VARCHAR(255))
BEGIN
SET @sql_query = CONCAT('SELECT * FROM users WHERE username = ''', username, '''');
PREPARE stmt FROM @sql_query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
Preventive Approach (Correct Method with Parameterization):
CREATE PROCEDURE GetUser(IN username VARCHAR(255))
BEGIN
SELECT * FROM users WHERE username = username;
END;
By avoiding the direct concatenation of parameters and opting for parameterized queries within stored procedures, developers can substantially mitigate the risk of SQL injection attacks.
This approach enhances security by treating user inputs as data and not as executable code, aligning with best practices to safeguard against potential malicious exploitation.
5. Conduct Continuous Scanning and Penetration Testing
Regular security audits and code reviews involve thorough examinations of the application’s codebase. Automated tools and manual inspections help identify and address potential vulnerabilities, ensuring ongoing security.
AppTrana’s embedded DAST scanner ensures continuous inspection for security vulnerabilities like SQL injection in your code. This tool not only automates the vulnerability assessment process but is also equipped with manual pen testing capabilities.
Regular security audits, code reviews, and penetration testing collectively contribute to a proactive approach to identifying and addressing vulnerabilities.
6. Adopt the Least Privilege Principle
Limiting permissions to the minimum necessary reduces the impact of a successful SQL injection attack. Granting only specific privileges required for the application decreases the potential damage.
Example (using MySQL):
GRANT SELECT ON database.users TO 'web_app'@'localhost';
By using this GRANT statement with the SELECT privilege, the example demonstrates a security best practice: providing the ‘web_app’ user with the minimum necessary permissions. This user can only execute SELECT queries on the ‘users’ table within the ‘database’ database.
If an attacker exploits a vulnerability and gains unauthorized access, the impact is minimized because the compromised user has restricted privileges, mitigating potential damage to the overall system.
7. Deploy Web Application Firewalls (WAF)
Web Application Firewall (WAF) monitors and filters incoming HTTP traffic, detecting and blocking SQL injection attempts and other malicious traffic. It can catch and neutralize known attack patterns before they reach the application.
Rules can be configured to identify patterns associated with SQL injection, providing an additional layer of defense.
WAF Rule Example:
SecRule ARGS “(select|union|insert|delete|drop)” “deny,log”
This rule is like a security filter that scans incoming data for certain words often associated with SQL injection attempts. If it finds any, it denies the request and logs the occurrence, providing an additional layer of defense against potential SQL injection attacks.
Many organizations struggle to tackle issues such as outdated code, limited resources for testing and implementing changes, lack of awareness about application security, and the challenges posed by frequent updates in their applications.
Even minor code changes can introduce injection issues as such changes may not be subjected to a fully-fledged security review process in the development cycle.
When a vulnerability is identified, and immediate code fixes are not feasible due to time constraints or other considerations, a WAF can be used for virtual patching the vulnerabilities.
Virtual patching provides organizations with a rapid and effective means of securing their applications against known vulnerabilities, buying time to implement proper code fixes or updates.
A WAF can log and alert administrators about suspicious activities, providing insights into potential attack vectors and enabling timely responses.
Prevent SQL Injection with AppTrana WAAP
AppTrana WAAP help protect against SQL injection attacks by analyzing the incoming traffic to your web application and identifying malicious SQL code. It can then block the malicious traffic before it reaches your application, preventing the attack from occurring.
AppTrana uses a combination of machine learning, rule-based, and behavioral-based detection techniques to identify and block SQL injection attacks.
Additionally, AppTrana provides real-time visibility and reporting on all incoming traffic, so you can see what is happening on your application and quickly respond to potential threats.
You can start by determining if your website has SQL Injection risks with AppTrana Free Trial.
Stay tuned for more relevant and interesting security articles. Follow Indusface on Facebook, Twitter, and LinkedIn.