The State of SQL Injection
SQL injection (SQLi) has a history that is older than Internet Explorer (which according to Gen Z was the start of civilization). There have been thousands of breaches caused by SQL injection and an endless amount of well-documented best practices and tools to help prevent it. So surely, surely we learned our lesson from these breaches and SQLi is no longer an issue.
We have been monitoring the number of SQL injections discovered in open-source and closed-source projects to see if we are getting better. With the recent news coming that stolen data from the MOVEit SQL injection breach is bring sold for companies like Amazon, we decided to give you a sneak peek into our up-and-coming State of Injection report for 2025.
Spoiler, turns out we are still terrible at preventing SQL injection.
What is SQL injection?
SQLi is a vulnerability that occurs when a program uses untrusted user input directly in a query to a SQL database. A malicious user can then insert their own code and manipulate the query allowing the malicious user to access private data, bypass authentication or delete data. The example below shows how an insecure SQL query for a user login page is vulnerable to an SQLi authentication bypass attack.
There are many different types of injection attacks like code injection or cross-site scripting (XSS). But SQLi specifically has played a prominent role in breaches for a very long time and comes as a shock to many that we still need to discuss this in 2024.
How an SQLi attack happens
1. Vulnerable query
Example of a vulnerable query where user input is directly used in the query
2. SQL injection attack
SQL is injected into the user input field of an authentication page
3. Query run with payload
Payload comments out the password check so the query ignores this step
SQL injection by the numbers:
- 6.7% of all vulnerabilities found in open-source projects are SQLi
- 10% for closed-source projects!
- An increase in the total number of SQL injection in open-source projects (CVE’s that involve SQLi) from 2264 (2023) to 2400 (2024) is expected.
- As a percentage of all vulnerabilities, SQL injection is getting less popular: a decrease of 14% and 17% for open-source and closed-source projects respectively from 2023 to 2024
- Over 20% of closed source projects scanned are vulnerable to SQL injection when they first start using security tooling
- For organizations vulnerable to SQL injection, the average number of SQL injection sites is nearly 30 separate locations in the code
We reviewed how many SQLi vulnerabilities were discovered in open-source packages in 2023 and so far in 2024. We then compared that to closed-source projects that have been discovered by Aikido Security. Unsurprisingly, we are still seeing shocking numbers of SQL injection in both closed and open-source projects. 6.7% of all vulnerabilities discovered in open-source projects in 2024 are SQL injection vulnerabilities while 10% of vulnerabilities discovered in closed-source projects were SQL injection vulnerabilities. This may not seem like a lot but it is frankly shocking that in 2024 we are still struggling to cope with some of the most basic vulnerabilities we know of.
The only good news we have is that this number is a 14% decrease from 2023 in open-source and a 17% reduction in closed-source projects as a percentage of all vulnerabilities found. However, the total number of SQLi found is expected in increase from 2264 in 2023 to over 2400 by the end of 2024 in open-source projects.
Preventing SQL injection
Apparently, there isn’t enough information on the internet just yet on how to prevent SQL injection so here is an overview of the options available in 2025:
1. Use Prepared Statements and Parameterized Queries
In the example at the start of this Blog Post, we showed vulnerable code because it takes untrusted user input and uses it directly in a query. To avoid this we should use prepared statements which means defining your query first and then adding user input later. This separates the command and data stream, fixing the problem completely. A great solution, but not always possible or used!
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
user_id = 5 # Example safe input
# Safe query using parameterized query
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id))
2. Server-side input/schema validation
Input validation can be effective in preventing SQLi. For example, if your API expects an email address or a credit card number, it’s easy to add validation for those cases.
3. Use SAST & DAST tools to discover SQLi
One of the most terrifying elements of SQLi is that it is easily discovered by adversaries often being described as a low-hanging fruit vulnerability. Part of this reason is because tools like DAST can automatically discover them. This can be used to our advantage and we can introduce these tools into our development process to catch them early.
Next-gen SAST tools like Aikido also allow you to autofix the issues right from within the platform.
4. Implement an in-app firewall
An in-app firewall monitors traffic and activity inside your application and can detect attacks including injection and SQLi. This is more effective than a traditional WAF as it sits inside your application and is able to tokenize expected queries and block requests that change the command structure of the query.
Shameless plug ;) for Aikido’s new launch: Zen, the in-app firewall for peace of mind at runtime. Get Zen and it will automatically block critical injection attacks and zero-day threats in real-time, before they ever reach your database.
5. Avoid Dynamic SQL Where Possible
Dynamic SQL generation through string concatenation is highly vulnerable to SQL injection. Whenever possible, stick to static, pre-defined queries and stored procedures that don’t rely on user-generated content for SQL structure.
6. Allowlisting and escaping
In some cases, you cannot avoid Dynamic SQL, such as when querying dynamic tables, or when you want to order by a user-defined column and direction. In those cases you have no other option than to rely on regular expression allowlisting or escaping. Escaping is taking user input that contains dangerous characters used in code like ‘>’ and turning them into a safe form. Ether by adding backslashes before them or transforming them into a symbol code. Note that this is different not only for each database type but can also depend on connection settings such as charset.
Will we ever see the end of SQLi?
While there is some promise in the fact we have seen a somewhat significant decrease in the number SQLi vulnerabilities found it is still disheartening to see that a vulnerability that predates the game DOOM is still such a significant threat to the landscape. The truth is, I can’t see this getting much better. As we introduce more tools to help us code faster, developers are getting less in touch with the core coding principles and these AI tools are notoriously bad at suggesting vulnerable code with injection vulnerabilities included.
It is not all Doom and gloom (pun intended) though, we are seeing significant improvements in a new generation of SAST tools that are far more effective at discovering and fixing these vulnerabilities has the ability to drastically change the threat landscape.
Signing off for now, don’t forget to:
Discover and automatically fix SQL injection with Aikido AI SAST Autofix
Checkout Zen and prevent injection attacks as they happen
Bonus: SQL History throughout history
Ever since we started talking about security in our applications we have talked about SQL injection. It was even featured at number 7 on the very first OWASP top 10 chart in 2003, in 2010 was included in the injection category and took the number 1 spot until 2021. One of the first large-scale attacks documented involving SQL injection was when the clothing company Guess was targeted resulting in the leak of credit card numbers. Since then SQL injection has been a regular guest among security headlines.