CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-3GJW-F78C-VVPW

GHSA-3GJW-F78C-VVPW: Denial of Service via Unhandled Out-of-Bounds Indexing Panic in tokio-postgres

Alon Barad
Alon Barad
Software Engineer

Aug 24, 2026·6 min read·5 visits

Executive Summary (TL;DR)

Unvalidated DataRow field counts in tokio-postgres allow a rogue or compromised database server to crash client applications via an out-of-bounds panic.

An issue was discovered in the tokio-postgres library for Rust prior to version 0.7.18. A trust assumption mismatch between the PostgreSQL protocol messages sent by a server and how they are parsed and indexed by the client-side library allows a rogue or compromised database server to trigger a Denial of Service (DoS) crash via an unhandled out-of-bounds slice indexing panic.

Vulnerability Overview

tokio-postgres is an asynchronous, pure-Rust client implementation for the PostgreSQL database. It is widely deployed across high-performance Rust web backends, microservices, and data pipelines to manage database connection pools and execute SQL statements asynchronously. The library communicates directly with PostgreSQL backends using the standard PostgreSQL frontend/backend protocol.

A trust assumption mismatch exists within the library regarding messages sent by the database server. Specifically, the client assumes that the database server will only transmit well-formed row data that strictly matches the previously declared query schema. This architectural trust exposes an attack surface where a rogue or manipulated database server can trigger unexpected state transitions on the client.

The vulnerability manifests as an unhandled out-of-bounds slice indexing panic. This occurs when the client attempts to access fields of a row that contains fewer fields than the columns advertised in the query's metadata. Because the panic is unhandled, it typically terminates the executing thread or aborts the entire Rust process, leading to a Denial of Service (DoS) of the client application.

Root Cause Analysis

To understand the root cause of this vulnerability, we must examine the sequence of messages in the PostgreSQL backend-to-frontend protocol. When a client issues a query, the backend server first sends a RowDescription (type 'T') message. This message contains metadata about each column, including its name, table OID, attribute number, data type, size, and modifier. This message establishes the structure and column count N of the expected output.

Following the description, the backend transmits one or more DataRow (type 'D') messages containing the actual query results. A DataRow starts with a two-byte integer indicating the number of fields M present in that row, followed by length-value pairs for each field. Under normal conditions, the field count M must equal the column count N defined in the RowDescription message.

Prior to version 0.7.18, tokio-postgres did not validate that M is equal to N during row construction. The constructor parsed the DataRow into an internal vector of byte ranges representing each field's offset. When an application later attempted to access a column at index I (where 0 <= I < N), the library mapped the index to the corresponding range in the vector. If M < N and the application requested an index I >= M, the program attempted to access an element beyond the bounds of the parsed ranges vector, causing an indexing panic.

Code Analysis

We can analyze the vulnerability by inspecting the code inside tokio-postgres/src/row.rs prior to the patch.

// Vulnerable Row constructor
impl Row {
    pub(crate) fn new(statement: Statement, body: DataRowBody) -> Result<Row, Error> {
        let ranges = body.ranges().collect().map_err(Error::parse)?;
        Ok(Row {
            statement,
            body,
            ranges,
        })
    }
}

In this implementation, ranges is populated directly from the DataRowBody without evaluating its length against the number of expected columns in statement.columns(). The application retrieves data using column indexes, which are bounds-checked against the Statement columns, not the actual ranges vector.

The patch introduces strict validation in both Row::new and SimpleQueryRow::new functions:

// Patched Row constructor
impl Row {
    pub(crate) fn new(statement: Statement, body: DataRowBody) -> Result<Row, Error> {
        let ranges = body.ranges().collect().map_err(Error::parse)?;
        let row = Row {
            statement,
            body,
            ranges,
        };
        // The DataRow field count is sent by the server independently of the
        // RowDescription column count; a mismatch would make column accessors
        // index `ranges` out of bounds and panic, so reject it up front.
        if row.ranges.len() != row.statement.columns().len() {
            return Err(Error::parse(io::Error::new(
                io::ErrorKind::InvalidData,
                "DataRow field count does not match the number of columns",
            )));
        }
        Ok(row)
    }
}

This validation converts an inevitable out-of-bounds panic into a standard, recoverable Rust Result::Err wrapping an io::Error of type InvalidData.

Exploitation Mechanics

An attacker can exploit this vulnerability through three main vectors: hosting a rogue PostgreSQL database, compromising an existing database server, or executing a Man-in-the-Middle (MitM) attack to alter network packets. The vulnerability requires no authentication on the application side beyond standard database access configuration.

In a typical exploit scenario, the client application initiates a query expecting a multi-column result. The attacker-controlled server sends a valid RowDescription defining two columns but returns a DataRow with only one field.

When the client receives the data, the row is instantiated successfully because there is no constructor-level validation. The crash occurs when the application attempts to process the row, specifically when indexing into the ranges vector during column value extraction.

Impact Assessment & Security Context

The security impact of this vulnerability is a complete Denial of Service (DoS) of the client application. Because Rust's asynchronous execution model often routes multiple client requests through a shared thread pool, an unhandled panic can abort the task and, depending on panic behavior configurations (such as panic = "abort"), crash the entire executable.

The attack requires low complexity if the target application connects to external or user-provided database sources. In managed cloud environments where database endpoints are strictly controlled, exploitation requires either network-level interception (MitM) or prior compromise of the database host.

As this issue is tracked exclusively under the GitHub Advisory Database (GHSA-3GJW-F78C-VVPW) and does not have an assigned CVE identifier, standard scoring metrics like CVSS or EPSS percentiles from NVD are not available. However, a qualitative risk assessment places this at High severity because of the low effort required to crash consumer services once database communication is intercepted.

Remediation & Detection Guidance

Remediation requires upgrading the tokio-postgres library to version 0.7.18 or later. This can be verified by analyzing the dependency tree using the Cargo build tool.

cargo tree -p tokio-postgres

To prevent network-level exploitation such as packet manipulation, database connections must enforce strict TLS validation. Applications should avoid connecting to database servers over unencrypted connections or with disabled certificate checks.

// Secure connection configuration
let mut builder = native_tls::TlsConnector::builder();
// Ensure strict verification of the server's identity
builder.danger_accept_invalid_certs(false);
builder.danger_accept_invalid_hostnames(false);

Additionally, applications should handle database queries within structured boundaries that can recover from runtime errors, ensuring that database parsing failures do not lead to application crashes.

Official Patches

rust-postgresOfficial commit patch fixing the out-of-bounds row indexing vulnerability

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H

Affected Systems

tokio-postgres library client applications

Affected Versions Detail

Product
Affected Versions
Fixed Version
tokio-postgres
rust-postgres
< 0.7.180.7.18
AttributeDetail
CWE IDCWE-129
Attack VectorNetwork / Man-in-the-Middle / Malicious Database Connection
CVSS Score7.5 (Qualitative Assessment)
EPSS ScoreN/A (No CVE Assigned)
ImpactDenial of Service (DoS)
Exploit Statusnone
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
T1557Man-in-the-Middle
Credential Access / Lateral Movement
CWE-129
Improper Validation of Array Index

The product uses an input value to index an array, but it does not validate that the index is within the valid range.

Vulnerability Timeline

Vulnerability patched in rust-postgres repository
2026-06-12
Release tokio-postgres 0.7.18 published to crates.io
2026-06-12
GitHub Security Advisory GHSA-3GJW-F78C-VVPW published
2026-06-12

References & Sources

  • [1]GitHub Security Advisory GHSA-3GJW-F78C-VVPW
  • [2]Fix Commit
  • [3]tokio-postgres v0.7.18 Release Notes

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•GHSA-4PH6-MJV7-3FQ6
6.5

GHSA-4PH6-MJV7-3FQ6: Improper Handling of Untrusted DNS-over-HTTPS Response Data in netfoil

netfoil, an allowlist-based DNS proxy, failed to sanitize ALPN fields parsed from untrusted DNS-over-HTTPS (DoH) HTTPS Resource Records. This allowed attackers to inject ANSI escape sequences into log files or trigger Denial of Service (DoS) via uncontrolled memory allocations.

Alon Barad
Alon Barad
2 views•6 min read
•about 17 hours ago•CVE-2026-14669
8.8

CVE-2026-14669: PostgreSQL to_char() Timezone Abbreviation Heap-Based Buffer Overflow

CVE-2026-14669 is a critical heap-based buffer overflow vulnerability in PostgreSQL's date/time formatting function to_char(timestamptz). The flaw arises from unsafe copying of user-controlled timezone abbreviations into a fixed-size internal buffer. An authenticated database user can trigger this issue by setting a long POSIX timezone abbreviation containing custom formatting, allowing them to overwrite adjacent heap structures and hijack execution control to achieve remote code execution (RCE) with the privileges of the 'postgres' operating system user.

Alon Barad
Alon Barad
11 views•6 min read
•2 days ago•CVE-2026-63462
7.5

CVE-2026-63462: Unauthenticated Stack Overflow Denial of Service in Unleash Server

An unauthenticated remote denial of service vulnerability exists in the Unleash feature management platform. By submitting a crafted JSON payload containing deeply nested structures to an OpenAPI-validated endpoint, an attacker can trigger uncontrolled recursion within the error formatting module. This leads to a call-stack exhaustion (RangeError: Maximum call stack size exceeded) inside the Node.js runtime, causing the service to crash immediately without recovery.

Alon Barad
Alon Barad
11 views•6 min read
•2 days ago•CVE-2026-63004
5.5

CVE-2026-63004: Server-Side Request Forgery in Unleash Addon and Integration Subsystem

CVE-2026-63004 is a server-side request forgery (SSRF) vulnerability in the Unleash feature management platform. Authenticated administrators with CREATE_ADDON or UPDATE_ADDON privileges can exploit this vulnerability to initiate requests to loopback addresses, private networks, and cloud metadata endpoints, potentially leading to information disclosure and credential extraction.

Amit Schendel
Amit Schendel
9 views•8 min read
•3 days ago•CVE-2026-63466
4.1

CVE-2026-63466: Process-Wide Security Degradation via Global Module Mutation in Unleash

Prior to version 8.0.3, Unleash's Markdown event formatter directly mutated the global template-escaping function of the shared mustache Node.js module, resulting in a process-wide security degradation where HTML/Markdown escaping was permanently disabled for the application lifetime.

Alon Barad
Alon Barad
3 views•6 min read
•3 days ago•CVE-2026-76904
9.8

CVE-2026-76904: Unauthenticated SQL Injection in GeoTools PostGIS DataStore Component

A critical SQL injection vulnerability exists in the GeoTools open-source Java library. This vulnerability is situated within the post-processing phase of OGC Filter conversion inside the PostGIS DataStore module. Specifically, the `jsonArrayContains` function does not validate or sanitize its arguments before constructing PostgreSQL SQL/JSON path evaluation queries. An unauthenticated remote attacker can exploit this weakness by submitting crafted filters via standard OGC services like WFS or WMS to execute arbitrary SQL commands on the underlying database system.

Alon Barad
Alon Barad
17 views•5 min read