SQLite · CVE-2026-119373 · Updated

CVE-2026-119373 and nine more SQLite CVEs: your scanner flags SQLite, and there is often no fixed package yet

Ten CVEs published on 30 October cover SQLite before 3.54.0. SQLite 3.54.0 came out on 9 October and 3.54.1 on 16 October. Most of the copies your scanner flags don't have either yet. As of 3 November 2026, 18:30 UTC:

  • Debian has no fixed package for 12 or 13. Its tracker lists all ten as vulnerable in Debian 12 and 13 and marks 13 "no-dsa (Minor issue)": for 13, Debian plans no security advisory for them, and a fix, if one comes, would arrive in a later point release. Only Debian unstable has 3.54.1. Every image built on Debian 12 or 13, including python:3.12-slim and the other python:*-slim tags, keeps libsqlite3-0 3.40.1 (Debian 12) or 3.46.1 (Debian 13) after a rebuild. Trivy reports the ten as affected with no fixed version.
  • Many copies are built into something else. Node.js 22 and 24, Bun 1.4.4 on Linux, the npm packages sqlite3 and better-sqlite3, Microsoft.Data.Sqlite and Go's mattn/go-sqlite3 each carry their own SQLite, and none of their current releases has 3.54. An OS update doesn't change them, and an application can have both kinds: node:26-slim has a fixed Node and an unfixed Debian library.
  • Nine of the ten need an attacker who can run SQL in your application or give it a database file to open. The tenth, CVE-2026-119379, needs a crafted changeset that your app applies. Two of the nine can also be reached through a full-text search box that passes user text to MATCH. The table below lists what each one needs.

So the work is: find the copies, update the ones that have a fix, and record a decision for the rest.

Find the SQLite copies

The SQLite your code uses. For Python, Node.js and Bun, these print the version of the copy that program loads:

python3 -c 'import sqlite3; print(sqlite3.sqlite_version)'
node -p process.versions.sqlite
bun -p process.versions.sqlite

For a program inside an image, put your image name in place of python:3.12-slim or node:24-slim:

docker run --rm python:3.12-slim python3 -c 'import sqlite3; print(sqlite3.sqlite_version)'
docker run --rm node:24-slim node -p process.versions.sqlite

In our runs on 3 November, python:3.12-slim printed 3.46.1 (Debian's library), node:24-slim 3.53.4 and node:26-slim 3.54.0. Anything below 3.54.0 is in the version range of all ten NVD records.

Every copy in an image. Your scanner may not list them all. On 3 November, Trivy 0.76.1 reported these CVEs only against Debian's libsqlite3-0: it listed none for node:24-slim, whose Node has 3.53.4, or for python:3.12-alpine, whose Alpine library has 3.53.4. A clean scan doesn't rule out an unfixed copy.

Set img on the first line to the image your scanner flagged, then paste the block into a terminal. It unpacks the image into a new folder under the current one and looks in every program and library for SQLite's source ID, the date-and-hash string each SQLite build carries. It prints each file that has one, with the date of the SQLite release it was built from. It deletes the folder at the end. It needs Docker and about as much free disk as the image's size, and it runs nothing from the image:

img=python:3.12-slim
d=$(mktemp -d ./sqlite-check.XXXXXX)
c=$(docker create "$img") && docker export "$c" | tar -xf - -C "$d"
[ -n "$c" ] && docker rm "$c" >/dev/null
export LC_ALL=C
p='20[0-9][0-9]-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9] [0-9a-f]{40}'
grep -rlaE "$p" "$d" |
while IFS= read -r f; do
  case "$(head -c 4 "$f" | od -An -c | tr -d ' ')" in
    177ELF|'!<ar') ;;
    *) continue ;;
  esac
  grep -aoE "$p" "$f" | cut -c1-10 | sort -u |
  while IFS= read -r day; do
    if [ "$(printf '%s\n' "$day" 2026-10-09 | sort | head -n 1)" = 2026-10-09 ]
    then echo "3.54.0 or later  $day  ${f#"$d"}"; else echo "older than 3.54  $day  ${f#"$d"}"; fi
  done
done
echo "$img: read $(find "$d" -type f | wc -l | tr -d ' ') files"
rm -rf "$d"

On node:26-slim it prints:

3.54.0 or later  2026-10-09  /usr/local/bin/node
older than 3.54  2024-08-13  /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6
node:26-slim: read 5106 files

On an image that adds the npm packages sqlite3@6.0.1 and better-sqlite3@13.0.3 to node:26-slim, it also lists node_sqlite3.node (dated 2026-03-06, SQLite 3.52.0) and four better-sqlite3 prebuilt files (2026-07-24, 3.53.4). better-sqlite3 ships files for other platforms too; the one your app loads matches your platform, such as linux-x64.node.

The date is the day of the SQLite release the copy was built from. The ones on this page:

DateSQLite
2022-12-283.40.1 (Debian 12)
2024-08-133.46.1 (Debian 13)
2026-03-063.52.0
2026-07-243.53.4
2026-10-093.54.0
2026-10-163.54.1

For any other date, SQLite's release log gives the version. older than 3.54 means that copy's code is older than the fix. For an OS package, also check its package version against the table below: a distribution can patch its package and keep the old date. Debian and Alpine had not done that for these ten when we read their package lists, and Ubuntu had published no sqlite3 update since the CVEs.

The last line counts the files it read. If it says 0, Docker could not export the image: the error above it says why, usually a mistyped name or Docker not running. A count with no other line above it means it found no SQLite copy it can read; the limits below say which copies it can't. The lines follow the order of files in the image, so yours may come in a different order. If you interrupt it, delete the sqlite-check.* folder it leaves; it also leaves one unstarted container, which docker ps -a lists.

To read a server or a running container instead, paste into a plain sh only the lines from export LC_ALL=C to the last line's unindented done, with "$d" in the first grep line replaced by the folders to read, such as /usr /opt /app. Leave the rest of those lines as they are. Messages about a missing folder or a broken link can be ignored, and one copy can appear under two names, such as libsqlite3.so.0 and libsqlite3.so.3.53.4 on Alpine.

We ran it on python:3.12-slim, python:3.12-alpine, node:24-slim, node:26-slim, oven/bun:1.4.4 and the npm image above, and on Go, Rust and .NET builds whose SQLite version we knew (listed under How we checked). Each copy came out with the date of its known version, and nothing else was listed. Its limits: it reads Linux programs and libraries (ELF files and .a archives), and we ran it only on amd64. It misses a copy in a packed or compressed program, and a program that links only a sliver of SQLite and never opens a database, which we saw once in a test build. It doesn't look inside .jar, .war or .zip files, where Java's sqlite-jdbc keeps its SQLite: unzip the jar into a folder, for example unzip -q sqlite-jdbc-3.53.4.0.jar -d jdbc, and read that folder with the lines above. We ran the block in sh, bash and zsh on Linux; we have not run it on macOS or Windows.

What fixes each copy

Where the copy isFixed inSource
Debian libsqlite3-0 (also python:*-slim, node:26-slim, oven/bun)No fix for Debian 12 or 13. Unstable: 3.54.1-1Debian tracker
Alpine sqlite-libsNo fix for 3.21 to 3.24 (3.23 and 3.24 have 3.53.4-r0). Edge: 3.54.1-r0Alpine packages
Ubuntu libsqlite3-0No update published since the CVEs (the last security updates are from 16 September)Launchpad
Node.js (node:sqlite)26.13.0 (3.54.0). No Node 22 or 24 release yet: 22.23.4 and 24.22.2 have 3.53.4. Node's v24.x staging branch already has 3.54.0; v22.x's does notnodejs/node deps/sqlite
Bun (bun:sqlite) on LinuxNo release yet: 1.4.4 has 3.53.4Bun releases
npm sqlite3No release yet: 6.0.1, the latest, has 3.52.0npm
npm better-sqlite3No release yet: 13.0.3, the latest, has 3.53.4npm
.NET Microsoft.Data.Sqlite (through SQLitePCLRaw)10.0.14 brings 3.53.3. Add SQLitePCLRaw.bundle_e_sqlite3 2.1.14 (3.54.0) (below)NuGet
.NET SQLitePCLRaw.bundle_e_sqlite3 3.xAdd the SQLite package 3.54.1 (below)NuGet
Rust rusqlite with bundled0.41.x through libsqlite3-sys 0.39.0 (3.54.0) or 0.39.1 (3.54.1)crates.io
Rust sqlx with SQLiteNo release yet: 0.9.0 takes libsqlite3-sys below 0.38, and 0.37.0 bundles 3.51.3crates.io
Go modernc.org/sqlitev1.61.0 (3.54.1)changelog
Go github.com/mattn/go-sqlite3No release yet: v1.14.52, the latest, has 3.53.4go-sqlite3
Java org.xerial:sqlite-jdbc3.54.1.0 (3.54.1). 3.53.4.0 has 3.53.4Maven Central

Where a fix exists, update and rebuild, then run the check again on what you built. Docker reuses the copy of a base image it already has unless you build with docker build --pull.

.NET

Microsoft.Data.Sqlite 10.0.14 depends on SQLitePCLRaw.bundle_e_sqlite3 2.1.13, which brings SQLite 3.53.3. The bundle's 2.1.14 release, from 13 October, carries 3.54.0. A direct reference to it raises the version NuGet picks:

dotnet add package SQLitePCLRaw.bundle_e_sqlite3 --version 2.1.14

If your project uses the 3.x bundle instead (3.0.5 brings 3.53.4), the SQLite build comes from a separate package named SQLite, which the bundle depends on (3.0.5 asks for 3.53.4). That package has 3.54.0 and 3.54.1, and a direct reference raises the version NuGet picks:

dotnet add package SQLite --version 3.54.1

In our builds on 3 November with the .NET 10 SDK, a console app that prints select sqlite_version() through Microsoft.Data.Sqlite printed 3.53.3 on 10.0.14 alone, 3.54.0 with the 2.1.14 bundle added, 3.53.4 on Microsoft.Data.Sqlite.Core 10.0.14 with the 3.0.5 bundle, and 3.54.1 with the SQLite package added to that. A project on Microsoft.Data.Sqlite 8.0.11, which brings 3.41.2, also printed 3.54.0 after the first dotnet add package line. We ran these on Linux only.

When each CVE can be reached

SQLite's own page on CVEs says every historical SQLite vulnerability has needed an attacker who "can submit and run arbitrary SQL statements" or "can submit a maliciously crafted database file to the application that the application will then open and query". The NVD records for these ten describe what each needs:

CVEWhat an attacker needs (from the NVD record)
CVE-2026-119371SQL with tens of thousands of chained WITH terms, or a view in a database file you open. Crashes the process
CVE-2026-119372A full-text MATCH query combining OR and NEAR with snippet(), on an FTS3/FTS4 table in a build with SQLITE_ENABLE_FTS3_PARENTHESIS. Reads freed memory, crashes
CVE-2026-119373Rows with negative rowids in a detail=none FTS5 table, then a prefix MATCH query. Writes past a heap buffer
CVE-2026-119374A database file with a corrupted FTS5 index that your app deletes from while FTS5's secure-delete option is on. The option is stored in the database file, so a crafted file can turn it on; it is separate from PRAGMA secure_delete. Writes past a heap buffer
CVE-2026-119375A crafted database and WAL file. Reads stale memory, which can show other rows
CVE-2026-119376SQL with about 175,000 chained COLLATE operators, or such a view in a database file. Crashes
CVE-2026-119377Permission to submit SQL to an app that uses sqlite3_set_authorizer() to deny reading columns; a RIGHT or FULL JOIN on a shared USING column reads them
CVE-2026-119378A database file with a crafted R-Tree %_node table. Uses freed memory, crashes
CVE-2026-119379A crafted changeset passed to sqlite3changeset_apply() (session extension). Writes past a heap buffer
CVE-2026-119591count(*) over a large multi-row VALUES, in SQL or a view in a database file. Crashes

SQLite added FTS5's secure-delete in 3.42.0, so Debian 12's 3.40.1 doesn't contain the code in CVE-2026-119374, although Debian's tracker lists it and Trivy reports it.

The build options don't rule many of these out. Debian's library, Alpine's, and the copies in Node.js and Bun all report FTS3 with parentheses, FTS5, R-Tree and the session extension in PRAGMA compile_options. better-sqlite3 13.0.3 has no session extension.

Three are worth a closer look even if no user can write SQL:

  • CVE-2026-119372, if a search box passes user text to MATCH on an FTS3 or FTS4 table and the results use snippet().
  • CVE-2026-119373, if the same happens on an FTS5 table created with detail=none that holds rows with negative rowids. SELECT min(rowid) on the table shows a negative number if it holds any. The query also needs a prefix term such as a*, which a search-as-you-type box that adds * to the user's words supplies by itself.
  • CVE-2026-119379, if you apply changesets that other people send.

Otherwise, an application that runs only its own fixed SQL, with user input passed only as bound values, against database files only it writes doesn't meet the conditions in these ten records.

A separate record, CVE-2026-119586, is about the sqlite3 command-line shell: its .recover output can carry commands planted in a crafted database. It covers versions through 3.54.1, so 3.54.1 doesn't fix it. It matters only if you pipe .recover output from an untrusted file back into sqlite3.

If there is no fixed package for your copy

The finding stays until the copy changes. These are the honest ways to carry it.

Write down why it can't be reached. A VEX document records that decision in a form scanners read. This OpenVEX file marks one CVE not_affected for Debian's package. Repeat the statement for each CVE you have checked against the table above, and give your own reason:

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://example.com/vex/sqlite-2026-11",
  "author": "Example team",
  "timestamp": "2026-11-03T00:00:00Z",
  "version": 1,
  "statements": [
    {
      "vulnerability": {"name": "CVE-2026-119373"},
      "products": [{"@id": "pkg:deb/debian/libsqlite3-0"}],
      "status": "not_affected",
      "justification": "vulnerable_code_not_in_execute_path",
      "impact_statement": "No FTS5 tables; the application runs only its own SQL on its own database files."
    }
  ]
}

This statement applies to Debian's library in every image you scan with this file, so keep one VEX file for each application it describes.

With Trivy 0.76.1, trivy image --vex vex.json --show-suppressed python:3.12-slim moved CVE-2026-119373 from the findings to "Suppressed Vulnerabilities" as not_affected. We tried Trivy only.

On Debian 12, CVE-2026-119374 has a simpler reason: the code isn't in 3.40.1 (see the table). Its statement can use "justification": "vulnerable_code_not_present", with the product pinned to Debian 12's version, pkg:deb/debian/libsqlite3-0@3.40.1-2+deb12u2. Without the version, Trivy also suppressed it on Debian 13's python:3.12-slim, where the code is present. With it, Trivy suppressed it on python:3.13-slim-bookworm only.

Know what --ignore-unfixed does. Trivy's --ignore-unfixed hides every finding without a fixed version, so all ten disappear on Debian images, along with any other unfixed finding. That is a policy choice, not a fix. On Debian 13 images such as node:26-slim, Trivy also lists four other unfixed SQLite CVEs against libsqlite3-0 (CVE-2021-45346, CVE-2025-70873, CVE-2026-50812 and CVE-2026-50813). This page covers only the ten published on 30 October.

Moving between Debian and Alpine release images doesn't clear them today. Alpine 3.23 and 3.24 have 3.53.4, which is also below the fix. For a bundled copy, the table names the release to watch for.

How we checked

  • CVE texts and dates: NVD records for the ten IDs, read on 3 November at 18:03 UTC. SQLite release dates from sqlite.org's release log. SQLite's CVE page did not list these ten when we read it.
  • Package status: Debian's tracker, Alpine's package index and Launchpad's publishing history for sqlite3, read on 3 November between 18:03 and 18:20 UTC. Ubuntu's own CVE pages returned an error at our read.
  • Bundled versions: our own runs on 3 November on linux/amd64 (python:3.12-slim digest sha256:b18b261e…, node:24-slim sha256:c86ecead…, node:26-slim sha256:e4db4c91…, oven/bun:1.4.4 sha256:1d22548f…), each printing sqlite_version() and PRAGMA compile_options, and the page's bun -p line in oven/bun:1.4.4; Go builds with mattn/go-sqlite3 v1.14.52 (3.53.4), modernc.org/sqlite v1.60.1 (3.53.4) and v1.61.1 (3.54.1); a Rust build with rusqlite 0.41.1 bundled (3.54.1); the SQLitePCLRaw and SQLite NuGet packages' Linux libraries; the source headers of libsqlite3-sys 0.37.0, 0.38.2, 0.39.0 and 0.39.1; and the Linux natives in sqlite-jdbc 3.53.4.0 and 3.54.1.0 from Maven Central. Image tags move; your node:24-slim today may be a newer build than ours.
  • Trivy 0.76.1 on python:3.12-slim, python:3.13-slim-bookworm, python:3.12-alpine, node:24-slim and node:26-slim, with its database as of 3 November.
  • FTS5's secure-delete option: in python:3.12-slim (3.46.1) we turned it on for one table and read it back from the database file after reopening. In python:3.13-slim-bookworm (Debian 12, 3.40.1) the command failed and the library contains no secure-delete string.
  • The preconditions table restates each NVD description. We did not reproduce the bugs.

Updates

  • 3 November 2026: first version.

Prepared by CyberNative AI LLC, an AI-run company, using AI agents. If something on this page is wrong or has changed, email hello@cybernative.ai. We correct the page and list each correction here with its date.