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-JQCQ-XJH3-6G23
5.3

GHSA-JQCQ-XJH3-6G23: Denial of Service via Unbounded Allocation in pgproto3

Alon Barad
Alon Barad
Software Engineer

Mar 18, 2026·7 min read·3 visits

No Known Exploit

Executive Summary (TL;DR)

The pgproto3 Go package fails to validate the size and element count of PostgreSQL wire protocol messages during encoding, allowing an attacker to trigger massive memory allocations and cause a denial of service (DoS) via OOM.

A denial of service vulnerability exists in the github.com/jackc/pgproto3/v2 Go package due to the absence of bounds checking during PostgreSQL wire protocol message encoding. This flaw allows a misconfigured peer or malicious actor to cause excessive memory allocation, leading to application crashes via out-of-memory (OOM) errors.

Vulnerability Overview

The github.com/jackc/pgproto3/v2 package is a widely used Go implementation of the PostgreSQL wire protocol (version 3). It provides the foundational structures and methods for encoding and decoding protocol messages between PostgreSQL clients and servers. This component is crucial for applications, proxies, and drivers that interact with PostgreSQL databases at the protocol level.

The vulnerability, identified as GHSA-JQCQ-XJH3-6G23, is classified as a Denial of Service (DoS) flaw caused by Uncontrolled Resource Consumption (CWE-400). It occurs in the message encoding routines where the library fails to validate the size of data structures before allocating memory and writing out the serialized bytes. Specifically, limits defined by the PostgreSQL protocol specification are ignored during the Go struct serialization process.

An attacker interacting with an application that uses a vulnerable version of this library can submit inputs that result in the creation of exceptionally large message structures. When the application attempts to encode these structures into byte slices for network transmission, the library blindly attempts to process the unbounded data. This behavior leads directly to memory exhaustion and application termination.

Root Cause Analysis

The root cause of this vulnerability lies in the design of the Encode methods across various message types within the pgproto3 library. The PostgreSQL wire protocol strictly defines size limits for message attributes. For instance, the number of parameters, fields, or format codes in a message is typically represented by a 16-bit unsigned integer, establishing a hard limit of 65,535 items. Additionally, the overall length of a single protocol message is bounded.

In versions prior to v2.3.3, the Encode methods implemented in pgproto3 did not enforce these protocol-level constraints. The methods directly iterated over the lengths of Go slices (such as src.Parameters or src.Fields) and appended the data to a destination byte buffer. If a developer or a proxy application populated these structures with data exceeding the 16-bit limit, the library would proceed with the encoding phase without returning an error.

This oversight manifests during the byte slice append operations. The unbounded iteration causes the Go runtime to continuously allocate larger underlying arrays to accommodate the growing slice. Furthermore, because the element count exceeds the capacity of the protocol's 2-byte length field, the resulting encoded message is structurally malformed. The failure to validate input against protocol constraints thus results in simultaneous protocol corruption and severe memory bloat.

Code Analysis

The remediation of this vulnerability required structural changes to the API and internal logic of the pgproto3 encoding mechanisms. Prior to the fix, the Encode signature returned only a byte slice (Encode(dst []byte) []byte), making it impossible to gracefully report constraint violations to the calling function.

The patched version introduces an error return value, modifying the signature to Encode(dst []byte) ([]byte, error). The maintainers introduced a constant maxMessageBodyLen set to (0x3fffffff - 1), which corresponds to the standard PG_LARGE_MESSAGE_LIMIT of approximately 1GB. Two helper functions, beginMessage and finishMessage, were implemented to centralize the validation of total message lengths.

// Patched message length validation
const maxMessageBodyLen = (0x3fffffff - 1)
 
func finishMessage(dst []byte, sp int) ([]byte, error) {
    messageBodyLen := len(dst[sp:])
    if messageBodyLen > maxMessageBodyLen {
        return nil, errors.New("message body too large")
    }
    pgio.SetInt32(dst[sp:], int32(messageBodyLen))
    return dst, nil
}

Additionally, targeted checks were inserted before slice iterations to prevent the encoding of invalid element counts. The patch enforces the math.MaxUint16 limit on attributes such as parameter arrays. If the length of src.Parameters exceeds 65,535, the function immediately returns an error rather than attempting serialization.

// Patched bind.go with explicit bounds checking
func (src *Bind) Encode(dst []byte) ([]byte, error) {
    dst, sp := beginMessage(dst, 'B')
    
    if len(src.Parameters) > math.MaxUint16 {
        return nil, errors.New("too many parameters")
    }
    dst = pgio.AppendUint16(dst, uint16(len(src.Parameters)))
    // ... remainder of encoding logic
    return finishMessage(dst, sp)
}

Exploitation Methodology

Exploiting this vulnerability does not yield remote code execution or data exfiltration, but instead focuses purely on service availability. The attack vector depends entirely on the specific application architecture that relies on the pgproto3 library. The vulnerable application must accept attacker-controlled input and subsequently map that input into a pgproto3 message structure for encoding.

An attacker initiates the exploit by sending a payload that compels the target application to construct a message with an abnormally large number of elements. For example, in a custom database proxy written in Go, an attacker might submit a highly complex query or a crafted set of bind parameters. If the proxy decodes the external input and blindly populates the Bind or RowDescription structures, the structures will reflect the malicious size.

When the proxy eventually calls the Encode method to serialize the data for the upstream PostgreSQL server, the library triggers the unbounded allocation loop. The Go garbage collector struggles to keep up with the massive memory allocations, and the runtime eventually triggers an Out Of Memory panic, terminating the process and denying service to legitimate users.

Impact Assessment

The primary impact of this vulnerability is a complete loss of availability for the application utilizing the vulnerable package. The attack vector is strictly network-based and requires no authentication if the affected component exposes an unauthenticated ingestion path. The corresponding CVSS v3.1 vector evaluates to CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L, resulting in a base score of 5.3.

The severity of the denial of service scales directly with the deployment architecture. In a single-instance deployment, a successful exploit immediately halts operations. In clustered or containerized environments managed by orchestrators like Kubernetes, repeated exploitation causes constant pod restarts. This thrashing behavior severely degrades overall system performance and can trigger cascading failures across dependent microservices.

There is no impact on confidentiality or integrity. The vulnerability resides strictly in the allocation routines of the memory serialization process. The attacker cannot read arbitrary memory, nor can they alter existing database records. However, because pgproto3 is widely used in custom connection poolers and proxies, a widespread availability disruption in the data tier represents a significant operational risk.

Remediation Guidance

The definitive remediation for this vulnerability is upgrading the github.com/jackc/pgproto3/v2 module to version v2.3.3 or later. This version introduces the necessary validation boundaries to prevent malicious memory allocations. Because the Encode function signature has been deliberately modified to return an error interface, developers must update their implementation logic to handle these new error conditions appropriately.

To apply the update, administrators should execute go get github.com/jackc/pgproto3/v2@v2.3.3 in their project directory, followed by go mod tidy to clean up the module dependencies. After updating the module, a full recompilation and redeployment of the application is necessary to enforce the new constraints.

For systems where an immediate upgrade is not feasible, mitigation options are limited. Implementing strict input validation at the edge of the application is required to ensure that incoming requests cannot generate data sets containing more than 65,535 parameters or fields. Web Application Firewalls (WAFs) or API gateways can also be configured to enforce strict payload size limits, rejecting requests that exceed standard operational boundaries before they reach the vulnerable service.

Official Patches

jackcPatch Comparison
jackcRelease Notes

Technical Appendix

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

Affected Systems

github.com/jackc/pgproto3/v2 (Go module)

Affected Versions Detail

Product
Affected Versions
Fixed Version
github.com/jackc/pgproto3/v2
jackc
< 2.3.32.3.3
AttributeDetail
Vulnerability TypeDenial of Service (DoS)
CWE IDCWE-400
Attack VectorNetwork
CVSS v3.1 Score5.3
ImpactLoss of Availability (OOM Panic)
Exploit StatusNo public weaponized exploits
Patched Versionv2.3.3

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

Uncontrolled Resource Consumption

Vulnerability Timeline

Patch v2.3.3 released by maintainers (Estimated based on context)
2024-01-01

References & Sources

  • [1]GitHub Advisory: GHSA-JQCQ-XJH3-6G23
  • [2]Vulnerable Repository

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.