Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-78183

CVE-2026-78183: DBD::Pg Perl Module Buffer Overflow Flaw

CVE-2026-78183 is a heap buffer overflow in DBD::Pg version 3.21.0 for Perl that occurs in quote_float function when handling special numeric literals. This article covers technical details, affected versions, and mitigation.

Updated:

CVE-2026-78183 Overview

CVE-2026-78183 is a heap out-of-bounds write vulnerability in DBD::Pg version 3.21.0, the PostgreSQL database driver for Perl. The flaw resides in the quote_float() function inside quote.c, which was rewritten in the 3.21.0 release. When callers pass special floating-point literals such as NaN, Inf, +Inf, -Inf, Infinity, +Infinity, or -Infinity to $dbh->quote() with DBI::SQL_NUMERIC, the function allocates length + 1 bytes but writes length + 3 bytes into that buffer. Every recognized literal overflows the heap allocation by two bytes: a single quote character and a NULL terminator. The issue is tracked under CWE-787.

Critical Impact

Applications that pass attacker-influenced values to $dbh->quote() with the numeric type hint can trigger a two-byte heap overflow, corrupting adjacent heap metadata and potentially leading to remote code execution against Perl services backed by PostgreSQL.

Affected Products

  • DBD::Pg 3.21.0 for Perl
  • Perl applications using DBI with the PostgreSQL driver at version 3.21.0
  • Downstream distributions repackaging DBD-Pg-3.21.0

Discovery Timeline

Technical Details for CVE-2026-78183

Vulnerability Analysis

The defect lives in quote_float() inside quote.c. When a caller quotes a value with the numeric type hint, the function normally emits the bare numeric symbol followed by a NULL terminator and allocates length + 1 bytes. However, PostgreSQL requires special floating-point literals to be wrapped in single quotes so the parser can distinguish them from identifiers. For the recognized literals NaN, Inf, +Inf, -Inf, Infinity, +Infinity, and -Infinity (matched case-insensitively), the function writes an opening quote, the literal, a closing quote, and a NULL terminator—length + 3 bytes—into the length + 1 byte buffer. The two-byte overflow corrupts adjacent heap chunks. Because the corruption occurs in a widely used database driver reachable through standard DBI calls, network-facing Perl web applications that quote user-supplied numeric input are exposed.

Root Cause

The regression was introduced by the quote.c rewrite shipped in DBD::Pg 3.21.0. The rewritten quote_float() branch that handles infinity and NaN literals allocated storage sized for the bare literal but wrote the quoted form. The patched code allocates length + 3 bytes to accommodate both quotes and the NULL terminator.

Attack Vector

An attacker supplies a string matching one of the recognized special literals to any Perl code path that calls $dbh->quote($value, DBI::SQL_NUMERIC). A typical trigger is:

$dbh->quote("Infinity", DBI::SQL_NUMERIC);

Applications that accept numeric parameters from HTTP requests, message queues, or file input and forward them to quote() are exploitable without authentication when the surrounding service is network-reachable.

c
// Patched allocation in quote.c - Fix incorrect allocation when quoting floats
         (3 == length && 0 == strncasecmp(string, "Inf", 3)) ||
         (4 == length && 0 == strncasecmp(string, "+Inf", 4)) ||
         (4 == length && 0 == strncasecmp(string, "-Inf", 4))) {
-        New(0, new_string, length + 1, char);
+        New(0, new_string, length + 3, char);
         new_string_start = new_string;
         *new_string++ = '\'';
         Copy(string_start, new_string, length, char);

Source: GitHub Patch Commit 6d6f47e

Detection Methods for CVE-2026-78183

Indicators of Compromise

  • Perl or httpd worker processes crashing with SIGABRT or SIGSEGV shortly after handling requests containing values like Infinity, Inf, or NaN.
  • Heap corruption diagnostics such as malloc(): corrupted top size or free(): invalid next size in application logs when DBD::Pg 3.21.0 is loaded.
  • PostgreSQL query logs showing quoted infinity literals originating from untrusted sources.

Detection Strategies

  • Inventory installed Perl modules and flag any host reporting DBD::Pg version 3.21.0 via perl -MDBD::Pg -e 'print $DBD::Pg::VERSION'.
  • Scan source repositories for calls to $dbh->quote(..., DBI::SQL_NUMERIC) and audit whether the first argument can carry untrusted input.
  • Add web application firewall rules to alert on numeric parameters containing the tokens inf, infinity, or nan.

Monitoring Recommendations

  • Enable core dump capture and ASan or MALLOC_CHECK_=3 in staging to surface heap corruption during regression testing.
  • Forward Perl and web server crash telemetry to a centralized log store and alert on abnormal termination rates for services using DBD::Pg.
  • Track outbound PostgreSQL query patterns to detect anomalous quoting behavior against production databases.

How to Mitigate CVE-2026-78183

Immediate Actions Required

  • Upgrade DBD::Pg to version 3.21.1 or later, which contains the corrected allocation in quote_float().
  • Restart all long-running Perl processes, including mod_perl, FastCGI, and daemon workers, so the patched shared object is loaded.
  • Audit application code for direct use of $dbh->quote() with DBI::SQL_NUMERIC on untrusted input and prefer parameterized placeholders where possible.

Patch Information

The fix is available in DBD::Pg 3.21.1. See the upstream commits 6d6f47e and adacf1d, the GitHub Security Advisory GHSA-785p-fw3v-r822, and the MetaCPAN Release Changes for DBD-Pg-3.21.1.

Workarounds

  • Downgrade to DBD::Pg 3.20.x until the 3.21.1 release can be deployed.
  • Reject or sanitize inputs matching /^\s*[+-]?(inf(inity)?|nan)\s*$/i before they reach $dbh->quote().
  • Replace explicit quote() calls with bind parameters using $sth->execute($value), which routes numeric values through the safe integer and binary paths.
bash
# Upgrade DBD::Pg using cpanm and verify the installed version
cpanm DBD::Pg@3.21.1
perl -MDBD::Pg -e 'die "still vulnerable" if $DBD::Pg::VERSION eq "3.21.0"; print "DBD::Pg $DBD::Pg::VERSION\n"'

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.