Jul 2, 2026·6 min read·7 visits
Integer truncation in SQLite's aggregate query compiler allows remote code execution or denial of service through out-of-bounds heap reads and writes when processing queries with over 32,767 unique columns.
An integer truncation vulnerability (CWE-197) exists in SQLite before version 3.50.2 during the processing of aggregate queries with more than 32,767 distinct column references. This causes an internal 32-bit counter to truncate to a signed 16-bit integer, producing negative values that cause out-of-bounds heap operations in release builds.
SQLite is an embedded relational database engine utilized inside almost every major operating system, web browser, and enterprise application framework. The attack surface of SQLite expands when applications allow untrusted inputs to compile into executable database instructions. This specific vulnerability is an integer truncation flaw within the database engine's parsing and compilation pipeline.
The flaw exposes the system to heap-based buffer overflows during the compilation of complex aggregate queries. An attacker who is able to supply raw SQL queries to the compiler can exploit this truncation to corrupt memory. In systems with high-privilege SQL execution environments, this behavior can escalate to remote code execution.
Because SQLite runs inside the context of the calling process, memory corruption in the database engine translates directly to compromise of the parent application. The threat model is particularly critical for mobile platforms, native applications, and database management systems that perform client-side SQL execution. Securing these architectures requires a thorough understanding of compile-time logic.
The root cause of CVE-2025-6965 lies in the findOrCreateAggInfoColumn function within SQLite's query compilation subsystem. When parsing SQL statements containing aggregate functions like SUM(), COUNT(), or AVG(), SQLite maintains an internal count of distinct column references. This counter tracks where aggregate results are temporarily stored during execution.
If the number of unique column references within the aggregate expressions exceeds 32,767, the tracking index exceeds the storage capacity of a signed 16-bit integer. When the 32-bit compilation counter assigns its value to the 16-bit signed index variable, numeric truncation occurs. A value of 32,768 (0x8000) wraps to -32,768 due to the sign-bit interpretation.
In debug builds, assertion statements immediately halt program execution upon detecting invalid negative index states. In production (non-debug) release builds, these diagnostic assertions are compiled out to optimize performance. The negative index value then flows unchecked into subsequent memory calculation routines, resulting in out-of-bounds pointer arithmetic.
The vulnerability involves how the compiler manages the AggInfo structure and its nested arrays. Prior to the patch, the parser did not enforce a low-level limit on the number of aggregate terms. This omission allowed the internal counter to increment past the boundary of a signed 16-bit short.
Let's construct the visual state transition using a Mermaid diagram to show the flow of compilation index truncation:
The patch in trunk commit 5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8 prevents this scenario by inserting validation checks directly inside src/expr.c. Below is a conceptual representation of the vulnerable pattern versus the patched logic:
// Vulnerable Code Path
struct AggInfo_col {
short iCol; // Signed 16-bit integer used for indexing
// ... other fields
};
int findOrCreateAggInfoColumn(Parse *pParse, AggInfo *pAggInfo, Expr *pExpr) {
// No validation on the aggregate column count before assignment
pAggInfo->aCol[pAggInfo->nColumn].iCol = (short)nColIndex; // Truncation happens here
pAggInfo->nColumn++;
}The patched version restricts the compilation count before any assignment is made:
// Patched Code Path (Trunk Fix)
int findOrCreateAggInfoColumn(Parse *pParse, AggInfo *pAggInfo, Expr *pExpr) {
if( pAggInfo->nColumn >= 32768 ){
sqlite3ErrorMsg(pParse, "too many terms in aggregate query");
return -1;
}
// The assignment is now guaranteed to remain within the range of a signed 16-bit integer
pAggInfo->aCol[pAggInfo->nColumn].iCol = (short)nColIndex;
pAggInfo->nColumn++;
}Exploitation of CVE-2025-6965 requires two primary prerequisites: the ability to execute arbitrary SQL commands on the target, and the absence of query length restrictions. The attacker constructs a SQL string consisting of more than 32,767 distinct columns referenced within aggregate statements. This query can reach several megabytes in size due to the verbose nature of naming tens of thousands of columns.
When the application processes this payload, the parser processes the columns and triggers the integer truncation in the compiler. Because the generated VDBE instructions contain negative indexes, the execution phase performs out-of-bounds lookups on the heap. Specifically, the base address of the aggregate column array is offset by a negative memory multiplier.
This calculation points to heap areas preceding the allocated buffer, where other critical database engine allocations reside. The application reads arbitrary data from these offsets and writes mutated values back to the same out-of-bounds locations during processing. Under precise heap layout manipulation, these out-of-bounds writes overwrite internal structure function pointers, allowing control flow hijack.
The security impact of CVE-2025-6965 is high, posing severe risks to applications integrating SQLite. The CVSS v3.1 base score of 7.7 represents a scenario where the attacker must have some privilege level to execute arbitrary SQL or must chain this with a SQL injection flaw. In situations where raw SQL injection exists, the impact elevates to remote code execution.
The EPSS score of 0.73495 demonstrates high vulnerability research interest and a high likelihood of target analysis. Although CISA has not yet added this vulnerability to the Known Exploited Vulnerabilities catalog, the technical availability of public details makes it a viable candidate for weaponization. Impacted operating systems include Apple macOS, iOS, iPadOS, and industrial systems like Siemens Ruggedcom Crossbow.
If successfully exploited, the vulnerability compromises the integrity of the host process, leading to a denial-of-service crash or complete execution control. Host configurations must treat this as a high-severity threat, especially in multi-tenant environments where users execute custom analytical database queries.
The definitive remediation is upgrading to SQLite version 3.50.2 or higher, which includes the hard limit checks on aggregate query sizes. For legacy systems where a full system upgrade is unfeasible, backported security updates are available on branches 3.32 and 3.42. These legacy patches include runtime bounds-checking to prevent negative offsets from being resolved during execution.
When binary updates are delayed, temporary mitigation strategies can reduce the attack surface. Applications should implement validation filters on inbound queries, dropping any requests exceeding 100 KB in size or containing more than 1,000 column declarations. Restricting database execution environments to read-only configurations does not prevent this heap corruption, as the compilation phase itself triggers the vulnerability.
Software developers must compile SQLite with strict compiler warning elevations to catch type conversions. Using flags like -Wconversion or -Wshorten-64-to-32 exposes truncation risks during the compilation of custom extensions. Regular static and dynamic analysis of native dependencies remains a critical practice to prevent native memory safety flaws from affecting higher-level applications.
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:L| Attribute | Detail |
|---|---|
| CWE ID | CWE-197 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 7.7 (High) |
| EPSS Score | 0.73495 (99.40th percentile) |
| Impact | Memory Corruption / Remote Code Execution |
| Exploit Status | PoC Available |
| KEV Status | Not listed |
Truncation of a primitive type to a smaller type, leading to data loss and unexpected sign-extension or wrap-around.
An integer overflow vulnerability in the Windows kernel-mode HTTP driver (HTTP.sys) allows an unauthenticated remote attacker to execute arbitrary code with kernel privileges or cause a Denial of Service via a specially crafted sequence of HTTP request headers.
A memory corruption vulnerability exists in the FTS5 (Full-Text Search 5) extension of SQLite prior to version 3.53.2. An attacker can construct a malicious database file containing corrupt FTS5 page data. Querying this database triggers out-of-bounds reads and heap-based buffer overflows, potentially causing a crash or arbitrary code execution.
A mass assignment vulnerability (CWE-915) in n8n's self-service settings API endpoint (PATCH /me/settings) allows authenticated Single Sign-On (SSO) users to disable SSO enforcement for their accounts by injecting administrative parameters. This bypasses organizational identity provider controls and multi-factor authentication (MFA).
CVE-2026-55699 (also identified as GHSA-4gxm-v5v7-fqc4) is a critical path traversal and arbitrary directory deletion vulnerability in the pnpm package manager. The issue exists because the manifest validation process fails to prevent relative path segments within the package 'bin' keys. When a malicious package containing structured path traversal markers is globally installed and later manipulated, pnpm resolves the target paths through path.join() and passes the resolved paths to a recursive deletion function, resulting in arbitrary directory removal.
A path traversal vulnerability in pnpm stage download allows malicious registries or compromised package manifests to overwrite arbitrary files on the victim's filesystem via unvalidated package name and version fields.
GHSA-WW5P-J6CJ-6MQQ is a technical credential exposure vulnerability in Nezha Dashboard prior to version 2.2.5. The vulnerability allows authenticated administrative users or actors possessing scoped read-only Personal Access Tokens (PATs) to exfiltrate plaintext third-party API credentials, secret keys, and webhook authorization headers due to a lack of data redaction during API object serialization.