Jun 19, 2026·6 min read·15 visits
TypeORM's UpdateQueryBuilder and SoftDeleteQueryBuilder allowed SQL injection via the orderBy direction parameter when targeting MySQL or MariaDB. An initial fix was bypassed via string-based API signatures, but the vulnerability is fully mitigated in the latest releases.
A critical SQL injection vulnerability was discovered in TypeORM's UpdateQueryBuilder and SoftDeleteQueryBuilder when targeting MySQL and MariaDB backends. The flaw allows unauthenticated remote attackers to execute arbitrary SQL commands because input validation was bypassed on certain method signatures. The initial patch was incomplete, leaving a bypass open, which was resolved in the final security update.
TypeORM is an Object-Relational Mapper (ORM) widely integrated into enterprise Node.js ecosystems to model database entities and execute queries safely. Within TypeORM, the UpdateQueryBuilder and SoftDeleteQueryBuilder components translate programmatic JavaScript or TypeScript API calls into compiled database updates. These query builders expose critical methods, including orderBy and addOrderBy, designed to let developers specify the order in which rows should be processed.
In standard relational databases, sorting rows during write-based events is highly restricted. However, the MySQL and MariaDB engines explicitly support ORDER BY syntax inside standard UPDATE and DELETE commands. This capability means that TypeORM must generate target SQL statements containing ordering instructions when running on top of MySQL or MariaDB backends.
This architectural detail exposes a significant vulnerability surface area if user input is allowed to reach the sorting direction parameter. Without rigorous validation, arbitrary characters injected into this parameter pass through the query compiler directly to the database. This failure leads to unauthenticated SQL injection, exposing relational schemas and application data to exploitation.
The root cause of this vulnerability lies in the inconsistent validation architecture across TypeORM query builder subclasses. While the SelectQueryBuilder implemented early syntactic validations, the builders responsible for database writes did not possess matching safeguards. Specifically, UpdateQueryBuilder and SoftDeleteQueryBuilder permitted raw string parameters to pass directly to compilation routines.
When a developer invokes the orderBy() method with string arguments, the query builder stores these options inside the query expression map. During compilation, the builder invokes the internal method createOrderByExpression(). This method reads from the expression map and directly concatenates the raw value string into the final query string template.
In an initial attempt to mitigate this issue (implemented in PR #12217), developers introduced the centralized validation helper validateOrderByCondition(). However, this fix contained a fatal design flaw: it only checked the input parameters if the root argument was structured as an object. When a developer invoked the string signature—such as orderBy(columnName, orderDirection)—the validation logic was entirely bypassed, writing the raw direction input straight to the expression map.
To trace the flaw, we can analyze the control flow and structural design of the vulnerable paths. The diagram below illustrates how string-based arguments bypass the validation routine introduced in the partial patch.
The vulnerable TypeScript code within UpdateQueryBuilder.ts before the final patch illustrates this critical architectural blind spot:
// Vulnerable code in UpdateQueryBuilder.ts
orderBy(
sort?: string | OrderByCondition,
order: "ASC" | "DESC" = "ASC",
nulls?: "NULLS FIRST" | "NULLS LAST",
): this {
if (sort) {
if (typeof sort === "object") {
// Centralized validation helper is ONLY triggered for object structures
this.validateOrderByCondition(sort)
this.expressionMap.orderBys = sort
} else {
// String signature bypasses validation entirely and writes raw values
if (nulls) {
this.expressionMap.orderBys = {
[sort as string]: { order, nulls },
}
} else {
this.expressionMap.orderBys = { [sort as string]: order }
}
}
}
return this;
}During query compilation, the createOrderByExpression method simply performed direct string concatenation, as shown below:
protected createOrderByExpression() {
const orderBys = this.expressionMap.orderBys
if (Object.keys(orderBys).length > 0)
return (
" ORDER BY " +
Object.keys(orderBys)
.map((columnName) => {
if (typeof orderBys[columnName] === "string") {
return (
this.replacePropertyNames(columnName) +
" " +
orderBys[columnName] // Direct unvalidated string concatenation
)
}
// Object handling logic omitted...
})
)
}An attacker exploits this vulnerability by injecting SQL structures into the sorting direction parameter. In MySQL and MariaDB, the ORDER BY clause accepts lists of expressions separated by commas. Consequently, injecting a comma allows the attacker to append a secondary, completely arbitrary SQL statement to the database processor.
To trigger this behavior, an attacker submits a payload structured to introduce a time-based delay, such as ASC, (SELECT SLEEP(5)). If the underlying query builder compiles this string, the resulting database command will call the SLEEP function sequentially for each record matching the update filter. This produces a measurable delay in the HTTP response time.
By systematically altering the parameters of the subquery, the attacker can verify true/false conditions. This allows character-by-character extraction of tables, schemas, and system metadata. Furthermore, because this injection occurs inside an UPDATE or SOFT DELETE statement, it can alter database state as part of the primary transaction.
The impact of this SQL injection vulnerability is classified as high because it allows malicious actors to execute arbitrary commands within the database engine. Attackers can bypass built-in access controls, modify critical operational tables, or purge complete datasets. In configurations where database services run with elevated operational privileges, the risk increases dramatically.
If the database configuration permits reading or writing local system files, attackers can leverage SQL injection to write arbitrary web shells to the underlying host. This turns database manipulation into remote code execution. Additionally, attackers can retrieve system variables, environment credentials, and active configuration settings, which compromises connected upstream services.
The CVSS v3.1 vector evaluates to CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N. While the vulnerability is restricted to MySQL and MariaDB installations, these engines power a large percentage of web projects, expanding the threat landscape for unpatched Node.js backends.
Remediation requires upgrading the typeorm dependency to a version containing the definitive fix merged in commit 1b66c44d0410bdc56a0dcefb46be41867ec0fffc. This patch secures the library by executing centralized validation across all signatures and adding compilation-time schema checks. This defense-in-depth ensures that malformed payloads fail to compile even if they bypass setter checks.
If upgrading the package immediately is not feasible, developers must implement strict validation layers at the application boundary. Ensure that any variable mapped to the sort direction parameter is restricted strictly to an explicit allowlist consisting of "ASC" or "DESC". This stops the malicious input before it can be processed by TypeORM.
Furthermore, implement database privileges following the principle of least privilege. Limit database users from accessing administrative functions such as administrative sleep APIs or shell-execution privileges. Deploying Web Application Firewalls (WAF) configured with patterns to block semicolon usage, nested subqueries, and commas inside order-by fields provides an additional layer of security.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
typeorm TypeORM | < 0.3.20 | 0.3.20 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-89 |
| Attack Vector | Network |
| CVSS v3.1 Score | 8.1 (High) |
| Affected Dialects | MySQL, MariaDB |
| Vulnerability Class | SQL Injection |
| Exploit Status | Proof-of-Concept Available |
| Patch Status | Fully Patched (Commit 1b66c44) |
The software constructs an SQL command using externally-influenced input, but it does not neutralize or incorrectly neutralizes special elements that can modify the intended SQL command.
A critical heap out-of-bounds (OOB) write vulnerability exists in the Linux kernel's IPv6 RPL (Routing Protocol for Low-Power and Lossy Networks) Segment Routing Header (SRH) processing logic. The vulnerability is located within net/ipv6/exthdrs.c, specifically in the ipv6_rpl_srh_rcv function. Under specific circumstances, when a packet containing a compressed RPL Source Routing Header is processed, segment swapping can reduce the common-prefix length, causing the recompressed header to grow. Because the kernel fails to validate available headroom on intermediate segments, a buffer underflow occurs during skb_push. This leads to an integer wrap in the MAC header offset pointer during MAC header rebuilding, causing a 14-byte out-of-bounds memory write roughly 64 KiB past the socket buffer.
CVE-2026-58263 is a high-severity Mutation Cross-Site Scripting (mXSS) vulnerability affecting Jodit Editor prior to version 4.12.28. The flaw exists in Jodit's built-in clean-html sanitizer plugin, which fails to securely parse and sanitize nested elements containing foreign namespaces like MathML and SVG. Attackers can bypass sanitization by smuggling malicious payload elements inside rawtext container tags like style inside a MathML node, leading to DOM mutation and unauthenticated arbitrary script execution in the context of the user's browser session.
Jodit Editor versions prior to 4.13.6 are vulnerable to client-side Cross-Site Scripting (XSS). The clean-html plugin's sanitization routine performs case-sensitive lookups against uppercase-only element blacklists. When processing XML-based foreign namespaces such as SVG or MathML, DOM engines preserve the lowercase format of tags. Because Jodit's denyTags check fails to normalize tag casing, malicious script blocks nested inside foreign namespace elements completely bypass validation and serialize directly into the editor output.
A critical code injection vulnerability exists in Savon, a widely used SOAP client library for Ruby, prior to version 2.17.2. The vulnerability resides within the Savon::Model.all_operations module, where operation names fetched from a target Web Services Description Language (WSDL) document are dynamically evaluated via module_eval without sanitization. An attacker capable of manipulating the target WSDL document (e.g., through Man-in-the-Middle attacks, DNS hijacking, or Server-Side Request Forgery) can execute arbitrary Ruby code in the context of the parent application process.
An integer conversion overflow vulnerability exists in the XCF decoder of ImageMagick before version 6.9.13-51 and 7.1.2-26. The issue arises from mixed-type arithmetic that promotes calculation results to floating-point representations, causing an undefined cast back to integer. Under optimizing compilers, this undefined behavior results in bounds checks being bypassed, allowing out-of-bounds heap reads.
An authenticated file upload validation bypass vulnerability exists in the REDAXO CMS Mediapool addon in versions 5.18.2 through 5.21.0. Under permissive web server configurations, this allows authenticated users with media upload privileges to achieve remote code execution via multi-segment extension file uploads.