CVE-2026-76848 in TypeORM
Summary
by MITRE • 08/24/2026
TypeORM's SelectQueryBuilder.distinctOn accepts an array of strings and stores it on the expression map without validation. For PostgreSQL-family drivers, createSelectDistinctExpression in src/query-builder/SelectQueryBuilder.ts joins that array and interpolates the result into the generated statement as SELECT DISTINCT ON (values), with no escaping, quoting, identifier validation or allowlist, and without routing the values through replacePropertyNames or the driver's escape helper. Because the interpolation point is a parenthesized SQL expression list rather than an identifier-only position, a supplied element may carry arbitrary expressions, including correlated subqueries. An application that forwards a client-controlled value into distinctOn, for instance to let a caller choose a deduplication column, allows that client to read data anywhere the application's database role can reach through boolean or time-based inference, independently of the entity being queried. validateOrderByCondition, the allowlist check guarding the orderBy family in the same class, is not applied to this path.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 08/24/2026
The vulnerability identified in TypeORM’s SelectQueryBuilder.distinctOn method represents a critical SQL injection flaw stemming from insufficient input validation and improper handling of user-supplied data during query construction. Specifically, when developers utilize the distinctOn function to specify columns for deduplication in PostgreSQL-family databases, the framework accepts an array of strings without performing any form of escaping, quoting, or identifier validation. This lack of sanitization allows attackers to inject arbitrary SQL expressions directly into the generated statement. The technical root cause lies in how TypeORM constructs the SELECT DISTINCT ON clause; it joins the provided array elements and interpolates them directly into the query string as a parenthesized expression list. Unlike standard column references, this position does not restrict input to simple identifiers, thereby permitting complex syntactic structures such as correlated subqueries or boolean logic expressions that can be executed within the context of the database engine.
From an operational perspective, this vulnerability enables severe data exfiltration and unauthorized access scenarios. Because the injected payload is treated as part of a valid SQL expression rather than a literal value, an attacker who controls input passed to distinctOn can manipulate the query execution flow. By injecting boolean-based or time-based inference payloads, such as conditional statements that trigger different response times or error messages based on database state, attackers can perform blind data extraction. This allows them to read sensitive information from any table accessible by the application’s database user account, effectively bypassing intended access controls and entity-level restrictions. The severity is compounded by the fact that existing security mechanisms within TypeORM are not applied to this specific code path; notably, the validateOrderByCondition function, which implements an allowlist check for order-by clauses in the same class, is entirely absent from the distinctOn implementation, leaving a significant gap in defense-in-depth strategies.
This vulnerability aligns with CWE-89 Improper Neutralization of Special Elements used in an SQL Command and falls under MITRE ATT&CK technique T1059 Command and Scripting Interpreter via database query manipulation or T1074 Data Staged for Exfiltration if the extracted data is prepared for transfer. The lack of parameterized queries or strict type checking for structural elements like distinct keys creates a predictable attack vector that can be exploited remotely without authentication in many web applications where user input directly influences query structure. To mitigate this risk, developers must avoid passing untrusted user input to the distinctOn method entirely. If dynamic column selection is required, it should be restricted to a hardcoded allowlist of known-safe identifiers rather than accepting arbitrary strings from external sources. Additionally, upgrading TypeORM to versions that implement stricter validation for structural query components or switching to raw SQL queries with explicit parameterization can reduce exposure. Security teams should also conduct code reviews focusing on all instances where user input influences the structure of database commands, ensuring that no other methods in the ORM framework suffer from similar oversights regarding identifier sanitization and expression injection prevention.