CVE-2026-128084: sqlite3-ruby: Possible SQL query truncation when a string is 4 GiB or larger
Summary
sqlite3-ruby cast Ruby string lengths (long) to int before passing them to SQLite. On 64-bit platforms, a string of 4 GiB (2^32 bytes) or larger had its length wrap, so SQLite saw only the first length mod 2^32 bytes. An attacker who controls the length of a SQL string could truncate the query, for example dropping a trailing WHERE clause. The affected paths are:
- the SQL passed to Database#prepare, #execute, and related methods - String and Blob values passed to Statement#bindparam and related methods - String and Blob values returned from SQL functions and aggregates defined in Ruby (Database#createfunction, #createaggregate, and related methods)
sqlite3 v2.10.2 raises RangeError when any of these strings is longer than INTMAX bytes.
Severity
The sqlite3-ruby maintainers have evaluated this as medium severity (CVSS 4.8). Exploitation requires an attacker to get at least 4 GiB into a single SQL string or bound value. Most deployments reject a request body that large before the application sees it, and the server must hold several copies of the string in memory.
A truncated bound value is only a prefix of the attacker's input, so the bind paths matter only where the application validated the full value. A truncated SQL string is more serious: when the attacker's input is inlined into the SQL, the clauses that follow it are dropped. If a dropped clause contained a bind placeholder, binding raises SQLite3::RangeException instead of running the query.
Mitigation
Upgrade to sqlite3 v2.10.2 or later.
As a workaround for earlier versions, reject SQL strings and bound values of 4 GiB or larger before passing them to sqlite3-ruby, or limit request body size well below 4 GiB.
Credit
This issue was responsibly reported by Luke Jahnke from elttam.
Other sources
sqlite3 provides Ruby bindings for the SQLite3 embedded database. Prior to 2.10.2, sqlite3-ruby casts Ruby string lengths to int before passing SQL through Database#prepare, bound String or Blob values through Statement#bindparam, and String or Blob results from Ruby-defined SQL functions and aggregates through Database#createfunction and Database#createaggregate. On 64-bit platforms, a string of 4 GiB (2^32 bytes) or larger can wrap the length so SQLite processes only a prefix. A truncated SQL string can drop trailing clauses such as a WHERE condition, while a truncated bound value matters only when the application validated the full value before binding it. Exploitation requires the application and server to accept and retain the unusually large attacker-controlled string. If a dropped SQL clause contained a bind placeholder, binding raises SQLite3::RangeException instead of running the query. This issue is fixed in version 2.10.2.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
rubygems/sqlite3to a version that resolves this vulnerability.Fixed in 2.10.2 - Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Fixed in 2.10.2 - Compensating control
For earlier versions, reject SQL strings and bound values that are 4 GiB or larger before passing them to sqlite3-ruby.
Event History
Frequently Asked Questions
Which environments are realistically exposed?
Exposure is limited to 64-bit platforms where an attacker can cause a single SQL string or bound value to reach at least 4 GiB. Most deployments reject request bodies of that size before the application processes them, and the server must be able to hold several copies of the string in memory.
What application interfaces should be reviewed?
Review SQL passed to Database#prepare, Database#execute, and related methods, plus String and Blob values passed through Statement#bind_param and related methods. Also review Ruby-defined SQL functions and aggregates created with Database#create_function, Database#create_aggregate, and related APIs when they return String or Blob data.
What is the remediation?
Use sqlite3-ruby v2.10.2. This version raises RangeError when a relevant string exceeds INT_MAX bytes instead of converting its length to an int.
What can be done if upgrading is not immediately possible?
Enforce size limits below 4 GiB for SQL text and bound String or Blob values before they reach sqlite3-ruby. Retain request-size limits and avoid application paths that construct attacker-controlled multi-gigabyte SQL strings or parameter values.