Introduction
A heap buffer overflow in SQLite's FTS5 full text search extension, patched in version 3.53.2, allows attackers to crash applications or potentially execute arbitrary code by supplying a crafted database file with malicious index metadata. With SQLite estimated to power over one trillion databases across every major mobile and desktop operating system, every major web browser, and the standard libraries of Python and PHP, the theoretical blast radius of a memory corruption vulnerability in this library is difficult to overstate, even when practical exploitation requires specific preconditions.
Technical Information
Root Cause: Integer Underflow in fts5ChunkIterate()
CVE-2026-11824 is classified as CWE-122 (Heap-based Buffer Overflow) with a CVSS v3 base score of 7.8 (High) and a CVSS v4 base score of 8.5 (High). The complete CVSS v4 vector is CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N.
The vulnerable code resides in the fts5ChunkIterate() function within ext/fts5/fts5_index.c. This function is responsible for iterating over data chunks stored in FTS5 index leaf pages during MATCH query evaluation. FTS5 is SQLite's optional full text search extension, enabled at compile time via the SQLITE_ENABLE_FTS5 build flag.
Each FTS5 leaf page carries a metadata field called szLeaf that describes the size of the page's usable content. The vulnerable code path computes the number of remaining bytes to process by subtracting a fixed offset (at least 4) from szLeaf. When a crafted database supplies a szLeaf value smaller than 4, this subtraction underflows. Because the arithmetic uses unsigned integers, the underflow wraps around to produce an extremely large positive value (CWE-190: Integer Overflow or Wraparound serves as the root cause mechanism). The function then interprets this inflated value as the number of bytes remaining in the buffer and proceeds to copy data well past the end of the heap allocated buffer.
Attack Flow
The exploitation proceeds through five stages:
Stage 1: Malicious Database Construction. The attacker crafts a SQLite database file containing an FTS5 virtual table. The database includes corrupt continuation page metadata in the FTS5 shadow table (t_data), with at least one page specifying a szLeaf value smaller than 4 (for example, zero).
Stage 2: Integer Underflow Trigger. When the victim application opens the database and executes an FTS5 MATCH query, fts5ChunkIterate() processes the continuation page. It subtracts a fixed offset from the szLeaf value. With szLeaf below 4, the unsigned subtraction wraps around, producing a massively inflated remaining byte count.
Stage 3: Inflated Byte Count Propagation. The function proceeds under the belief that there are far more bytes remaining in the buffer than actually exist.
Stage 4: Heap Buffer Overflow. The inflated byte count causes reads or writes past the end of the heap allocated buffer. The overflow data is attacker controlled because it originates from the crafted database content.
Stage 5: Impact. The overflow can cause a crash (denial of service) or, with a more sophisticated exploit, arbitrary code execution.
Preconditions
The CVSS v4 vector indicates a local attack vector requiring user interaction but no privileges. The SQLite project confirms that all historical SQLite vulnerabilities require at least one of two preconditions: (1) the attacker can submit and run arbitrary SQL statements, or (2) the attacker can submit a maliciously crafted database file that the application will then open and query. For CVE-2026-11824, the second precondition applies. The target application must be compiled with SQLITE_ENABLE_FTS5 and must open the attacker's database and execute an FTS5 MATCH query against it.
Historical Pattern in fts5ChunkIterate
This is the second vulnerability in fts5ChunkIterate across a seven year span:
| Vulnerability | Year | Type | Fix Version |
|---|---|---|---|
| CVE-2019-9937 | 2019 | NULL Pointer Dereference | 3.28.0 |
| CVE-2026-11824 | 2026 | Heap Buffer Overflow (integer underflow) | 3.53.2 |
The recurrence of vulnerabilities in this same function underscores the complexity of safely implementing high performance text indexing over variable length records with insufficient boundary validation.
Proof of Concept
A public proof of concept exists in the official SQLite source tree as the regression test file ext/fts5/test/fts5corruptA.test, added in fix commit 4a5ad516ea93 on 2026-05-11. The test constructs a corrupt FTS5 database and triggers the overflow via a MATCH query. On unpatched builds, this causes a heap buffer overflow; on patched builds it safely returns a corruption error.
The full Tcl test script (artifact 944c40f8da0f5db5):
source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5corruptA ifcapable !fts5 { finish_test return } sqlite3_fts5_may_be_corrupt 1 do_execsql_test 1.0 { CREATE VIRTUAL TABLE t USING fts5(x, detail='full'); INSERT INTO t(t, rank) VALUES('pgsz', 32); } set big [string repeat "a " 200] do_execsql_test 1.1 { INSERT INTO t(rowid, x) VALUES(1, $big) } do_test 1.2 { db eval { SELECT min(rowid) AS base_rowid, count(*) AS page_count FROM t_data WHERE rowid>1000 } {} } {} do_test 1.3 { for {set ii 0} {$ii < 5} {incr ii} { db eval { INSERT INTO t_data(rowid, block) VALUES( $base_rowid + $page_count + $ii, zeroblob(4) ); } } db eval { INSERT INTO t_data(rowid, block) VALUES( $base_rowid + $page_count + 5, unhex('00000080' || 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC') ); } set {} {} } {} db close do_test 1.4 { set hex [hexio_read test.db 0 [file size test.db]] set off [string first "023061018310" $hex] set hex [string replace $hex $off [expr $off+11] 023061018370] hexio_write test.db 0 $hex } {6144} sqlite3 db test.db do_catchsql_test 1.5 { SELECT rowid FROM t WHERE t MATCH 'a' } {1 {fts5: corruption found reading blob 137438953481 from table "t"}} sqlite3_fts5_may_be_corrupt 0 finish_test
How the PoC Works
-
An FTS5 virtual table
tis created withdetail='full'and a small page size of 32 bytes, forcing the indexer to generate multiple data pages for even modest content. -
A large text string (200 repetitions of
"a ") is inserted, generating multiple FTS5 data pages in thet_datashadow table. -
Corrupt continuation pages are injected directly into
t_data. Five pages contain 4 byte zero blobs. A sixth page has a header of00000080(settingszLeafto 0) followed by 0xCC fill bytes, which serve as the attacker controlled overflow payload. -
The raw database file is binary edited: the hex sequence
023061018310is replaced with023061018370, inflating a storedszLeafvalue from0x10to0x70. This manipulation alters the FTS5 segment metadata to reference the injected corrupt pages. -
When the MATCH query
SELECT rowid FROM t WHERE t MATCH 'a'is executed against this corrupt database,fts5ChunkIterate()computes a negative (underflowed) remaining byte count from the maliciousszLeaf, causing a heap buffer overflow with the attacker controlled 0xCC data.
On patched builds (3.53.2+), the query safely returns: {1 {fts5: corruption found reading blob 137438953481 from table "t"}}.
Credit: Ashish Kunwar (@D0rkerDevil).
Patch Information
The SQLite project patched CVE-2026-11824 in version 3.53.2, released on 2026-06-03. The fix was developed across two coordinated check-ins that both landed on 2026-05-11.
Fix Commits
Check-in 4a5ad516ea93 on the trunk branch, authored by developer "dan" at 11:12 UTC. This was the initial fix commit.
Check-in 061febcf41ca on the branch-3.53 release branch, cherry picked by D. Richard Hipp (drh) at 12:00 UTC to ensure the fix shipped in the 3.53.x maintenance line.
Both commits carry the same description: "Fix potential buffer overwrite that could occur in fts5 when processing corrupt records." They modify the same source file, ext/fts5/fts5_index.c, changing the artifact hash from f8cfa37bb7 to 957534376f.
What the Patch Does
The patch adds bounds validation on the szLeaf metadata value before the subtraction occurs. If the value fails validation (i.e., it is smaller than the minimum expected offset), the function treats the record as corrupt and rejects it rather than proceeding with the dangerous memory operation. This prevents the integer underflow that would otherwise produce the inflated byte count.
Alongside the code fix, both commits introduced a new regression test file: ext/fts5/test/fts5corruptA.test (artifact 944c40f8da), which exercises the specific scenario of corrupt continuation page metadata to verify the fix.
A follow up commit, 87b6537311, was pushed to trunk shortly after (at 11:53 UTC on the same day) with the message "Improve detection of corrupt database records in fts5," adding further hardening of corrupt record detection in the FTS5 extension beyond the immediate CVE fix.
Downstream Patches
SUSE has issued a corresponding security update (SUSE-SU-2026:20771-1). Organizations should monitor advisories from mobile OS vendors, desktop OS vendors, browser vendors, and application frameworks that embed SQLite.
Affected Systems and Versions
All versions of SQLite prior to 3.53.2 are affected when compiled with the SQLITE_ENABLE_FTS5 flag.
Specifically:
- Vulnerable: SQLite versions before 3.53.2 with FTS5 enabled at compile time
- Fixed: SQLite 3.53.2 and later
- Not affected: SQLite builds that do not include the
SQLITE_ENABLE_FTS5compile flag (the vulnerable code path is unreachable)
Given SQLite's ubiquity, affected deployments potentially include:
- Every Android device, every iPhone and iOS device, every Mac, and every Windows 10/11 installation (if the platform's SQLite build includes FTS5)
- Firefox, Chrome, and Safari web browsers
- Applications using Python's or PHP's standard library SQLite bindings (if compiled with FTS5)
- Skype, iTunes, Dropbox, TurboTax, QuickBooks, and countless other applications embedding SQLite
- Television sets, set top cable boxes, and automotive multimedia systems
Organizations must verify whether their specific SQLite builds include the SQLITE_ENABLE_FTS5 flag to determine actual exposure.
Vendor Security History
SQLite has experienced a notable series of memory safety vulnerabilities, particularly in the FTS5 extension and in integer handling:
| CVE | Year | Type | Component | Fix Version |
|---|---|---|---|---|
| CVE-2019-9937 | 2019 | NULL Pointer Dereference | FTS5 fts5ChunkIterate | 3.28.0 |
| CVE-2020-13632 | 2020 | NULL Pointer Dereference | FTS3 matchinfo() | 3.32.2 |
| CVE-2021-20223 | 2021 | Incorrect Results | FTS5 | 3.35.0 |
| CVE-2025-3277 | 2025 | Buffer Overflow | concat_ws() | 3.49.1 |
| CVE-2025-6965 | 2025 | Integer Overflow / Array Overread | Aggregation | 3.50.2 |
| CVE-2025-52099 | 2025 | Integer Overflow | sqlite3_db_config | 3.50.0 |
| CVE-2025-7709 | 2025 | Integer Overflow / Heap Buffer Overflow | FTS5 tombstone pointers | 3.50.2+ |
| CVE-2026-11824 | 2026 | Heap Buffer Overflow (integer underflow) | FTS5 fts5ChunkIterate | 3.53.2 |
The FTS5 extension appears as a recurring source of memory safety issues, with three separate CVEs (2019, 2025, 2026) affecting the component. The 2025 cluster of integer overflow vulnerabilities highlights a systemic pattern in SQLite's handling of boundary arithmetic. The SQLite team's rapid fix cadence (bugs typically fixed "within hours of discovery") partially mitigates the risk from this pattern, but the recurrence warrants attention from organizations that depend on FTS5 in security sensitive contexts.
The SQLite project's stance that "CVEs about SQLite probably do not apply to your use of SQLite" is directionally correct for the majority of deployments. However, organizations building applications that accept externally sourced database files face genuine risk that the vendor's risk downgrade does not adequately capture.
References
- CVE-2026-11824 Detail, NVD
- SQLite Release 3.53.2 On 2026-06-03
- SQLite Check-in 061febcf41ca (branch-3.53 fix)
- SQLite Check-in 4a5ad516ea93 (trunk fix)
- Regression Test Artifact 944c40f8da0f5db5
- VulnCheck Advisory: SQLite before 3.53.2 Heap Buffer Overflow via FTS5 fts5ChunkIterate
- SQLite FTS5 Extension Documentation
- SQLite Vulnerabilities Page
- SQLite Defense Against The Dark Arts
- Most Widely Deployed and Used Database Engine
- CWE-122: Heap-based Buffer Overflow
- CWE-190: Integer Overflow or Wraparound
- CVE-2019-9937 Detail, NVD
- Ashish Kunwar (@D0rkerDevil) on HackerOne



