Skip to content
Article

What Is SQL Injection (SQLi)? Types and How to Prevent It

SQL injection exposes a database by letting user input slip into a query. We explain its types, the MOVEit case, and how to prevent and detect it.

Oğuzhan Gerçek··10 min read
What Is SQL Injection (SQLi)? Types and How to Prevent It

Short answer: SQL injection (SQLi) is a vulnerability in which user input slips into an SQL query and changes what the query means. Through it, an attacker can read data they are not authorized to see, bypass authentication, and modify or delete records. The vulnerability class has been known for two decades, yet it still ranks second on the 2025 CWE Top 25. The permanent fix is the parameterized query (prepared statement), which sends the value to the database as a separate parameter; least privilege, allowlist validation, a WAF and regular testing complement it.

What is SQL injection?

In OWASP's definition, an SQL injection attack is the insertion of an SQL query into an application through input data from the client. According to MITRE's CWE-89 entry, the weakness arises when a product builds an SQL command from externally influenced input and fails to neutralize, or incorrectly neutralizes, special elements that could change the intended command. SQL basics are in our SQL article, and the definition of a database is in our glossary.

How does SQL injection work?

A vulnerable application builds the query it sends to the database by joining fixed text with a value that comes from the user, so a word typed into a search box becomes part of the query. According to OWASP, the vulnerability needs two conditions: data enters the program from an untrusted source, and that data is used to build the query dynamically. If SQL syntax in the input is not removed or quoted, CWE-89 explains, the query may interpret that input as SQL rather than as data; and according to Microsoft, the database engine executes every syntactically valid query it receives.

Types of SQL injection

OWASP's testing guide, the WSTG, divides attacks into three classes according to how the data reaches the attacker:

  • In-band: Data is extracted through the same channel used to send the attack input and appears directly in the page. Error-based techniques, which gather information from database error messages, and UNION-based techniques, which combine the results of two queries, work this way.
  • Blind (inferential): No data is transferred; the attacker reconstructs it from how the database behaves. In boolean-based techniques the clue is a difference in page content, and in time-based techniques it is a delay in the response.
  • Out-of-band: Data is retrieved over a different channel, for example by email.

According to OWASP, blind attacks are often used when an application shows generic error messages but the vulnerable code has not been fixed. Hiding error messages does not close the hole, although CWE-89 still recommends that they contain only the minimal details useful to their intended audience.

The impact of SQL injection

CWE-89 and OWASP list the consequences of a successful attack:

  • Data leakage: Because SQL databases generally hold sensitive data, loss of confidentiality is a frequent result.
  • Authentication bypass: If passwords are checked with a poorly built query, an attacker may log in as another user without knowing the password (our brute force article).
  • Modifying and deleting data: Records can be changed or even deleted; if authorization data is held in the database, access rules can be rewritten as well.
  • Reaching the server: According to OWASP, an attacker may also be able to perform administrative operations on the database, read the contents of files on the server and, in some cases, issue commands to the operating system.

Why is SQL injection still an issue?

In the OWASP Top 10:2025, Injection fell from third place in 2021 to fifth (A05:2025); the category also covers XSS. According to OWASP, 100% of applications were tested for some form of injection, and SQL injection is a low-frequency, high-impact vulnerability linked to more than 14,000 CVEs.

On the 2025 CWE Top 25, published on December 11, 2025, CWE-89 ranks second, up from third in 2024. According to the CWE program, the list draws on 39,080 CVE records published between June 1, 2024 and June 1, 2025.

In their March 2024 Secure by Design alert, CISA and the FBI stress that software manufacturers keep building products with this defect, even though the vulnerability class has been known and documented for two decades and effective mitigations exist. The alert asks manufacturers to put their code through a formal review, and customers to ask their vendors whether they have done so.

A real example: MOVEit Transfer

According to the joint advisory AA23-158A that CISA and the FBI issued on June 7, 2023, the ransomware group CL0P (TA505) began exploiting a previously unknown SQL injection vulnerability (CVE-2023-34362) in MOVEit Transfer, Progress Software's managed file transfer product, on May 27, 2023. Internet-facing MOVEit applications were infected with a web shell named LEMURLOOT, which was then used to steal data from the underlying databases.

According to the NVD, the vulnerability could allow an unauthenticated attacker to gain access to the database; its CVSS 3.1 score is 9.8 (critical).

How to prevent SQL injection

The OWASP SQL Injection Prevention Cheat Sheet lists four primary defenses; the fourth, escaping all user input, is "strongly discouraged". According to CISA and the FBI, input sanitization is brittle and can frequently be bypassed. The other three defenses, plus least privilege, are:

  1. Parameterized queries (prepared statements): The SQL code is defined first, and the user's value travels to the query as a separate parameter. According to OWASP, the database then always distinguishes code from data; CISA and the FBI want this enforced across all applications.
  2. Properly built stored procedures: Written safely, they have the same effect. According to the OWASP Top 10:2025, however, a stored procedure that concatenates queries and data can still introduce SQL injection even when it is parameterized.
  3. Allowlist validation: Table names, column names and sort order cannot be passed as bound parameters; OWASP recommends mapping such values to legal, expected names, and treats input validation as a secondary defense in all cases.
  4. Least privilege: Application accounts get no DBA rights, an account that only needs to read is granted read access only to the tables it needs, and each application connects with its own database account (our IAM article).

A query written with a placeholder in Python's sqlite3 module looks like this:

import sqlite3

conn = sqlite3.connect("example.db")
customer_id = 1042  # value from a form or an API request

rows = conn.execute(
    "SELECT id, created_at, total FROM orders WHERE customer_id = ?",
    (customer_id,),  # the value travels as a separate parameter
).fetchall()

An ORM reduces the risk but does not remove it: according to OWASP, an ORM still allows unauthorized data access when user input is concatenated into queries. Django's documentation says its querysets are protected because they build queries with parameterization, while raw SQL should be used sparingly and with care.

Detection: code review, testing, WAF and logs

OWASP recommends combining source code review with automated testing, including fuzzing, to find injection flaws. The tests should cover parameters, headers, URLs, cookies, and the JSON and XML input that APIs carry. Adding SAST, DAST and IAST tools to the CI/CD pipeline also helps catch flaws before production. SAST analyzes source code and points to SQL injection by line, but produces many false positives; DAST usually scans the application from the outside. In NIST's definition, penetration testing mimics real-world attacks to find ways around security features (our penetration testing article); we cover regular scanning in our vulnerability scan service.

  • WAF: A web application firewall can stop known attack patterns, but CWE-89 rates its effectiveness as moderate, because it might not cover every input vector and can be bypassed with malformed input. There is more in our WAF article, and we run this layer in our application security (WAF) service.
  • Logs and SIEM: OWASP wants input validation failures and syntax errors logged, the logs sent to a central system such as a SIEM, and the responsible team alerted immediately about serious events (our SIEM and SOC article).

What to do when you find one

  1. If it is in a product, update it: For MOVEit, the required action in CISA's Known Exploited Vulnerabilities (KEV) catalog was to apply updates per the vendor's instructions (NVD entry). We explain the process in our patch management article and run it in our patch and vulnerability management service.
  2. If it is in your own code, parameterize the query and search the whole codebase for the same pattern: CISA and the FBI want the entire class of vulnerability eliminated, not a single instance. Meanwhile, a virtual patch on the WAF buys time; according to OWASP, it blocks the known exploitation path but does not remove the vulnerability.
  3. Look for traces: CISA's MOVEit advisory recommends investigating abnormal activity with a network monitoring tool and reviewing servers and Active Directory for new or unrecognized accounts.
  4. Assess the impact: If the leaked records include personal data, legal notification duties may apply (our data breach notification article).

Frequently asked questions

What does SQL injection mean? SQL injection, abbreviated SQLi, is a vulnerability in which user input slips into an SQL query and changes what the query means.

How does an SQL injection attack happen? The application builds the query by joining fixed text with the user's value, and the database executes every syntactically valid query it receives. The attacker shapes the input to fit that syntax and changes what the query does.

How do you prevent SQL injection? The core defense is the parameterized query; safely written stored procedures, allowlist validation and least privilege complement it.

Does a WAF stop SQL injection? It can block known patterns, but it might not cover every input vector. Fixing the code is what removes the vulnerability.

Does using an ORM prevent SQL injection? It reduces the risk, because ORMs such as Django's build queries with parameters. Where raw SQL is written or input is concatenated into a query, the vulnerability can still appear.

Sources