CWE-89 Base Stable High likelihood

Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

SQL Injection occurs when an application builds a database query using untrusted user input without properly sanitizing it. This allows an attacker to insert malicious SQL code that the database…

Définition

What is CWE-89?

SQL Injection occurs when an application builds a database query using untrusted user input without properly sanitizing it. This allows an attacker to insert malicious SQL code that the database executes, potentially letting them view, modify, or delete sensitive data.
This vulnerability happens because user-supplied data in forms, URLs, or cookies is directly concatenated into an SQL query string. The database cannot distinguish between legitimate query instructions and the injected malicious commands, treating the attacker's input as part of the SQL statement itself. To prevent this, developers must never directly embed user input into queries. Instead, use parameterized queries (prepared statements) or stored procedures, which ensure the database always treats input as data, not executable code. Proper input validation and the use of established ORM (Object-Relational Mapping) libraries also provide strong, layered defenses against this common attack.
Vulnerability Diagram CWE-89
SQL Injection Login form user: ' OR '1'='1 String-concat query SELECT * FROM users WHERE name='$u' AND pw='$p' → … OR '1'='1' AND pw='' always true Database returns all users → in Without parameterized queries, input becomes part of the SQL itself.
Impact réel

Real-world CVEs caused by CWE-89

  • SQL injection in security product dashboard using crafted certificate fields

  • SQL injection in time and billing software, as exploited in the wild per CISA KEV.

  • SQL injection in file-transfer system via a crafted Host header, as exploited in the wild per CISA KEV.

  • SQL injection in firewall product's admin interface or user portal, as exploited in the wild per CISA KEV.

  • An automation system written in Go contains an API that is vulnerable to SQL injection allowing the attacker to read privileged data.

  • chain: SQL injection in library intended for database authentication allows SQL injection and authentication bypass.

  • SQL injection through an ID that was supposed to be numeric.

  • SQL injection through an ID that was supposed to be numeric.

Comment les attaquants l'exploitent

Parcours de l'attaquant étape par étape

  1. 1

    In 2008, a large number of web servers were compromised using the same SQL injection attack string. This single string worked against many different programs. The SQL injection was then used to modify the web sites to serve malicious code.

  2. 2

    The following code dynamically constructs and executes a SQL query that searches for items matching a specified name. The query restricts the items displayed to those where owner matches the user name of the currently-authenticated user.

  3. 3

    The query that this code intends to execute follows:

  4. 4

    However, because the query is constructed dynamically by concatenating a constant base query string and a user input string, the query only behaves correctly if itemName does not contain a single-quote character. If an attacker with the user name wiley enters the string:

  5. 5

    for itemName, then the query becomes the following:

Exemple de code vulnérable

Vulnerable C#

The following code dynamically constructs and executes a SQL query that searches for items matching a specified name. The query restricts the items displayed to those where owner matches the user name of the currently-authenticated user.

Vulnérable C#
...
  string userName = ctx.getAuthenticatedUserName();
  string query = "SELECT * FROM items WHERE owner = '" + userName + "' AND itemname = '" + ItemName.Text + "'";
  sda = new SqlDataAdapter(query, conn);
  DataTable dt = new DataTable();
  sda.Fill(dt);
  ...
Charge utile de l'attaquant

However, because the query is constructed dynamically by concatenating a constant base query string and a user input string, the query only behaves correctly if itemName does not contain a single-quote character. If an attacker with the user name wiley enters the string:

Charge utile de l'attaquant
name' OR 'a'='a
Exemple de code sécurisé

Secure PHP

In this case, the programmer could apply a simple modification to the code to eliminate the SQL injection:

Sécurisé PHP
$id = intval($_COOKIE["mid"]);
  mysql_query("SELECT MessageID, Subject FROM messages WHERE MessageID = '$id'");
What changed: the unsafe sink is replaced (or the input is validated/escaped) so the same payload no longer triggers the weakness.
Liste de contrôle de prévention

How to prevent CWE-89

  • Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid [REF-1482]. For example, consider using persistence layers such as Hibernate or Enterprise Java Beans, which can provide significant protection against SQL injection if used properly.
  • Architecture and Design If available, use structured mechanisms that automatically enforce the separation between data and code. These mechanisms may be able to provide the relevant quoting, encoding, and validation automatically, instead of relying on the developer to provide this capability at every point where output is generated. Process SQL queries using prepared statements, parameterized queries, or stored procedures. These features should accept parameters or variables and support strong typing. Do not dynamically construct and execute query strings within these features using "exec" or similar functionality, since this may re-introduce the possibility of SQL injection. [REF-867]
  • Architecture and Design / Operation Run your code using the lowest privileges that are required to accomplish the necessary tasks [REF-76]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations. Specifically, follow the principle of least privilege when creating user accounts to a SQL database. The database users should only have the minimum privileges necessary to use their account. If the requirements of the system indicate that a user can read and modify their own data, then limit their privileges so they cannot read/write others' data. Use the strictest permissions possible on all database objects, such as execute-only for stored procedures.
  • Architecture and Design For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
  • Implementation While it is risky to use dynamically-generated query strings, code, or commands that mix control and data together, sometimes it may be unavoidable. Properly quote arguments and escape any special characters within those arguments. The most conservative approach is to escape or filter all characters that do not pass an extremely strict allowlist (such as everything that is not alphanumeric or white space). If some special characters are still needed, such as white space, wrap each argument in quotes after the escaping/filtering step. Be careful of argument injection (CWE-88). Instead of building a new implementation, such features may be available in the database or programming language. For example, the Oracle DBMS_ASSERT package can check or enforce that parameters have certain properties that make them less vulnerable to SQL injection. For MySQL, the mysql_real_escape_string() API function is available in both C and PHP.
  • Implementation Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright. When constructing SQL query strings, use stringent allowlists that limit the character set based on the expected value of the parameter in the request. This will indirectly limit the scope of an attack, but this technique is less important than proper output encoding and escaping. Note that proper output encoding, escaping, and quoting is the most effective solution for preventing SQL injection, although input validation may provide some defense-in-depth. This is because it effectively limits what will appear in output. Input validation will not always prevent SQL injection, especially if you are required to support free-form text fields that could contain arbitrary characters. For example, the name "O'Reilly" would likely pass the validation step, since it is a common last name in the English language. However, it cannot be directly inserted into the database because it contains the "'" apostrophe character, which would need to be escaped or otherwise handled. In this case, stripping the apostrophe might reduce the risk of SQL injection, but it would produce incorrect behavior because the wrong name would be recorded. When feasible, it may be safest to disallow meta-characters entirely, instead of escaping them. This will provide some defense in depth. After the data is entered into the database, later processes may neglect to escape meta-characters before use, and you may not have control over those processes.
  • Architecture and Design When the set of acceptable objects, such as filenames or URLs, is limited or known, create a mapping from a set of fixed input values (such as numeric IDs) to the actual filenames or URLs, and reject all other inputs.
  • Implementation Ensure that error messages only contain minimal details that are useful to the intended audience and no one else. The messages need to strike the balance between being too cryptic (which can confuse users) or being too detailed (which may reveal more than intended). The messages should not reveal the methods that were used to determine the error. Attackers can use detailed information to refine or optimize their original attack, thereby increasing their chances of success. If errors must be captured in some detail, record them in log messages, but consider what could occur if the log messages can be viewed by attackers. Highly sensitive information such as passwords should never be saved to log files. Avoid inconsistent messaging that might accidentally tip off an attacker about internal state, such as whether a user account exists or not. In the context of SQL Injection, error messages revealing the structure of a SQL query can help attackers tailor successful attack strings.
Signaux de détection

How to detect CWE-89

Automated Static Analysis

This weakness can often be detected using automated static analysis tools. Many modern tools use data flow analysis or constraint-based techniques to minimize the number of false positives. Automated static analysis might not be able to recognize when proper input validation is being performed, leading to false positives - i.e., warnings that do not have any security consequences or do not require any code changes. Automated static analysis might not be able to detect the usage of custom API functions or third-party libraries that indirectly invoke SQL commands, leading to false negatives - especially if the API/library code is not available for analysis.

Automated Dynamic Analysis Moderate

This weakness can be detected using dynamic tools and techniques that interact with the software using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The software's operation may slow down, but it should not become unstable, crash, or generate incorrect results.

Manual Analysis

Manual analysis can be useful for finding this weakness, but it might not achieve desired code coverage within limited time constraints. This becomes difficult for weaknesses that must be considered for all inputs, since the attack surface can be too large.

Automated Static Analysis - Binary or Bytecode High

According to SOAR [REF-1479], the following detection techniques may be useful: ``` Highly cost effective: ``` Bytecode Weakness Analysis - including disassembler + source code weakness analysis Binary Weakness Analysis - including disassembler + source code weakness analysis

Dynamic Analysis with Automated Results Interpretation High

According to SOAR [REF-1479], the following detection techniques may be useful: ``` Highly cost effective: ``` Database Scanners ``` Cost effective for partial coverage: ``` Web Application Scanner Web Services Scanner

Dynamic Analysis with Manual Results Interpretation SOAR Partial

According to SOAR [REF-1479], the following detection techniques may be useful: ``` Cost effective for partial coverage: ``` Fuzz Tester Framework-based Fuzzer

Correction automatique Plexicus

Plexicus détecte automatiquement CWE-89 et ouvre une PR de correction en moins de 60 secondes.

Codex Remedium analyse chaque commit, identifie cette faiblesse précise et livre une pull request prête à être relue avec le correctif. Pas de tickets. Pas de transferts.

Questions fréquentes

Frequently asked questions

Qu'est-ce que CWE-89 ?

SQL Injection occurs when an application builds a database query using untrusted user input without properly sanitizing it. This allows an attacker to insert malicious SQL code that the database executes, potentially letting them view, modify, or delete sensitive data.

Quelle est la gravité de CWE-89 ?

MITRE évalue la probabilité d'exploitation comme Élevée — cette faiblesse est activement exploitée et doit être priorisée pour la remédiation.

Quels langages ou plateformes sont affectés par CWE-89 ?

MITRE lists the following affected platforms: SQL, Database Server.

Comment puis-je prévenir CWE-89 ?

Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid [REF-1482]. For example, consider using persistence layers such as Hibernate or Enterprise Java Beans, which can provide significant protection against SQL injection if used properly. If available, use structured mechanisms that automatically enforce the separation between data and code. These mechanisms may be able to provide the relevant quoting,…

Comment Plexicus détecte et corrige CWE-89 ?

Le moteur SAST de Plexicus reconnaît la signature de flux de données de CWE-89 à chaque commit. Lorsqu'une correspondance est trouvée, notre agent Codex Remedium ouvre une PR de correction avec le code corrigé, les tests et un résumé d'une ligne pour le relecteur.

Où puis-je en savoir plus sur CWE-89 ?

MITRE publie la définition canonique à https://cwe.mitre.org/data/definitions/89.html. Vous pouvez également consulter la documentation OWASP et NIST pour des conseils adjacents.

Prêt quand vous l'êtes

Arrêtez de payer par développeur.
Commencez à fermer la boucle.

Plexicus est l'ASPM natif IA qui scanne, filtre, corrige, penteste et explique — de façon autonome. Développeurs illimités, dépôts illimités, actions IA à usage équitable. Vrai niveau gratuit, €269/mo annuel quand vous êtes prêt.