Dev.to Security 🔐 Cybersecurity 👁 0 📖 3 min read

CVE-2026-128084: CVE-2026-128084: Integer Truncation and SQL Query Truncation in sqlite3-ruby

CVE-2026-128084: Integer Truncation and SQL Query Truncation in sqlite3-ruby Vulnerability ID: CVE-2026-128084 CVSS Score: 4.8 Published: 2026-11-13 Prior to version 2.10.2, the sqlite3-ruby gem explicitly cast 64-b

CVE-2026-128084: Integer Truncation and SQL Query Truncation in sqlite3-ruby

Vulnerability ID: CVE-2026-128084
CVSS Score: 4.8
Published: 2026-11-13

Prior to version 2.10.2, the sqlite3-ruby gem explicitly cast 64-bit Ruby string lengths (long) to 32-bit signed integers (int) when invoking the underlying SQLite C API. On 64-bit platforms, providing a string of 4 GiB (2^32 bytes) or larger causes integer truncation, instructing SQLite to process only a prefix of the string. This flaw affects SQL query preparation, bound parameter values, and return values from custom Ruby-defined SQL functions and aggregates, allowing trailing SQL clauses such as WHERE restrictions to be silently dropped under specific conditions.

TL;DR

An integer truncation flaw (CWE-681) in sqlite3-ruby prior to 2.10.2 causes strings of 4 GiB or larger to wrap their length when passed to the SQLite C API on 64-bit systems. This truncation can drop trailing SQL clauses, such as authorization filters, or truncate bound parameters. Upgrading to sqlite3 version 2.10.2 resolves the issue by replacing raw C casts with CRuby's RSTRING_LENINT macro, which raises a RangeError when string lengths exceed INT_MAX.

Technical Details

  • Vulnerability ID: CVE-2026-128084 / GHSA-4fqr-96q8-xrfx
  • Weakness Class: CWE-681: Incorrect Conversion between Numeric Types
  • CVSS v3.1 Score: 4.8 Medium (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N)
  • Affected Component: sqlite3 RubyGem (< 2.10.2) on 64-bit platforms
  • Patched Version: sqlite3 >= 2.10.2
  • Impact: SQL query truncation (dropping trailing clauses) and bound parameter truncation
  • Exploit Status: No known public exploits; Not in CISA KEV

Affected Systems

  • sqlite3 RubyGem (sqlite3-ruby) on 64-bit platforms
  • sqlite3 (sqlite3-ruby): < 2.10.2 (Fixed in: 2.10.2)

Code Analysis

Commit: 41059aa

fix: raise RangeError on strings longer than INT_MAX

diff --git a/ext/sqlite3/database.c b/ext/sqlite3/database.c
index 5d16ac77..92aebabc 100644
--- a/ext/sqlite3/database.c
+++ b/ext/sqlite3/database.c
@@ -529,14 +529,14 @@ set_sqlite3_func_result(sqlite3_context *ctx, VALUE result)
                 sqlite3_result_blob(
                     ctx,
                     (const void *)StringValuePtr(result),
-                    (int)RSTRING_LEN(result),
+                    RSTRING_LENINT(result),
                     SQLITE_TRANSIENT
                 );
             } else {
                 sqlite3_result_text(
                     ctx,
                     (const char *)StringValuePtr(result),
-                    (int)RSTRING_LEN(result),
+                    RSTRING_LENINT(result),
                     SQLITE_TRANSIENT
                 );
             }
diff --git a/ext/sqlite3/statement.c b/ext/sqlite3/statement.c
index edaaa98b..35a2cd4e 100644
--- a/ext/sqlite3/statement.c
+++ b/ext/sqlite3/statement.c
@@ -75,7 +75,7 @@ prepare(VALUE self, VALUE db, VALUE sql)
 #endif
                  db_ctx->db,
                  (const char *)StringValuePtr(sql),
-                 (int)RSTRING_LEN(sql),
+                 RSTRING_LENINT(sql),
                  &ctx->st,
                  &tail
              );
@@ -279,7 +279,7 @@ bind_param(VALUE self, VALUE key, VALUE value)
                              ctx->st,
                              index,
                              (const char *)StringValuePtr(value),
-                             (int)RSTRING_LEN(value),
+                             RSTRING_LENINT(value),
                              SQLITE_TRANSIENT
                          );
             } else {
@@ -290,7 +290,7 @@ bind_param(VALUE self, VALUE key, VALUE value)
                                  ctx->st,
                                  index,
                                  (const char *)StringValuePtr(value),
-                                 (int)RSTRING_LEN(value),
+                                 RSTRING_LENINT(value),
                                  SQLITE_TRANSIENT
                              );
                 } else {
@@ -301,7 +301,7 @@ bind_param(VALUE self, VALUE key, VALUE value)
                                  ctx->st,
                                  index,
                                  (const char *)StringValuePtr(value),
-                                 (int)RSTRING_LEN(value),
+                                 RSTRING_LENINT(value),
                                  SQLITE_TRANSIENT
                              );
                 }

Mitigation Strategies

  • Upgrade the sqlite3 RubyGem to version 2.10.2 or later to enforce INT_MAX length checks via RSTRING_LENINT.
  • Enforce strict HTTP request payload size limits at the reverse proxy (e.g., Nginx client_max_body_size) and web application server layers to prevent multi-gigabyte allocations.
  • Use parameterized SQL queries with bind placeholders exclusively instead of string interpolation or concatenation.
  • Validate and restrict the maximum byte size of user-supplied strings and binary blobs at the application boundary before passing them to database methods.

Remediation Steps:

  1. Update the project Gemfile to specify gem 'sqlite3', '>= 2.10.2'.
  2. Run bundle update sqlite3 to fetch and lock the patched gem version.
  3. Ensure the application handles RangeError exceptions gracefully if external callers attempt to process data exceeding 2 GiB.
  4. Restart all Ruby application server processes (Puma, Unicorn, Sidekiq, etc.) to load the updated native extension.

References

Read the full report for CVE-2026-128084 on our website for more details including interactive diagrams and full exploit analysis.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.