Hello,

I discovered a security issue in the SQLite3 DBD driver of apr-util
(version 1.6.3, and it also exists in the current trunk).

The function dbd_sqlite3_bind() in apr_dbd_sqlite3.c reads a blob size
via atoi() from a user-supplied string and passes it directly to
sqlite3_bind_blob() without any validation against the actual length
of the data buffer.

An attacker can supply a size larger than the real data length,
causing an out‑of‑bounds read when SQLite copies the blob. This may
lead to information disclosure or a crash (DoS).

The issue affects the text‑based BLOB binding path (pquery/pselect
family). Binary BLOB binding (pbquery/pbselect) is not affected by
this specific code path, but it also lacks validation (a separate
issue).

The proposed patch adds a safety check: if the announced size exceeds
strlen(data), the parameter is bound as NULL instead of a blob. This
prevents the OOB read and falls back to a safe behavior.

This change assumes that text‑based BLOB bindings are only used for
textual data (the common case). For genuine binary data, callers
should migrate to the binary bind functions (pbquery/pbselect), which
already expect a binary size argument.

The patch follows the Apache C Language Style Guide (4‑space indent,
no tabs, brace placement, spacing around operators).

Please review and consider applying.

Thank you,
Max Lane
<[email protected]>

---
Index: dbd/apr_dbd_sqlite3.c
===================================================================
--- dbd/apr_dbd_sqlite3.c (working copy)
+++ dbd/apr_dbd_sqlite3.c (working copy)
@@ -458,7 +458,22 @@
                 char *data = (char *)values[j];
                 int size = atoi((char*)values[++j]);

                 /* skip table and column */
                 j += 2;

-                sqlite3_bind_blob(stmt, i + 1, data, size, SQLITE_STATIC);
+                /*
+                 * Validate that the announced size does not exceed the
actual
+                 * length of the data. Otherwise an attacker could cause an
+                 * out-of-bounds read in sqlite3_bind_blob().
+                 *
+                 * For binary BLOB data the binary bind functions
+                 * (pbquery/pbselect) should be used instead.
+                 */
+                if (size > (int)strlen(data)) {
+                    sqlite3_bind_null(stmt, i + 1);
+                }
+                else {
+                    sqlite3_bind_blob(stmt, i + 1, data, size,
SQLITE_STATIC);
+                }
                 }
                 break;

Reply via email to