Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-29785

CVE-2025-29785: quic-go Denial of Service Vulnerability

CVE-2025-29785 is a denial of service flaw in quic-go that allows attackers to trigger a nil-pointer dereference via crafted ACK packets. This post explains the technical details, affected versions, and mitigation steps.

Published:

CVE-2025-29785 Overview

CVE-2025-29785 is a null pointer dereference vulnerability in quic-go, a popular implementation of the QUIC protocol written in Go. The vulnerability exists in the loss recovery logic for path probe packets introduced in version v0.50.0. A malicious QUIC client can exploit this flaw to crash the server by sending crafted ACK packets, resulting in a denial of service condition.

The attack requires the attacker to first send valid QUIC packets from different remote addresses to trigger the path validation logic, causing the server to send path probe packets. Subsequently, the attacker sends specifically crafted ACK packets designed to trigger the nil-pointer dereference in the packet acknowledgment handling code.

Critical Impact

Malicious QUIC clients can crash quic-go servers by exploiting the path probe packet tracking logic, causing complete denial of service for all connected clients.

Affected Products

  • quic-go version v0.50.0

Discovery Timeline

  • 2025-06-02 - CVE-2025-29785 published to NVD
  • 2025-06-02 - quic-go releases version v0.50.1 containing the security patch
  • 2026-04-15 - Last updated in NVD database

Technical Details for CVE-2025-29785

Vulnerability Analysis

The vulnerability resides in the sent_packet_handler.go file within quic-go's internal acknowledgment handler. When processing ACK packets, the code attempts to remove path probe packets from the packet history. The original implementation assumed that a path probe packet would always exist in the history when an ACK is received for it. However, this assumption fails when the path probe packet has already been declared lost by the loss recovery mechanism.

The flaw is classified under CWE-248 (Uncaught Exception), though the actual manifestation is a null pointer dereference. When the RemovePathProbe() function returns nil (indicating the probe packet no longer exists in the history), the original code would panic with an error message. However, the vulnerable code path could reach this state through normal protocol operation if loss recovery had already processed the packet.

Root Cause

The root cause is improper handling of the case where a path probe packet has already been removed from the packet history due to loss detection. The original code assumed that an acknowledged path probe packet must always exist in the history, but the loss recovery logic could remove it before the ACK arrived. This creates a race condition between loss detection and ACK processing, resulting in a nil pointer being passed to subsequent operations.

Attack Vector

The attack is network-based and requires no authentication or user interaction. An attacker can exploit this vulnerability by:

  1. Establishing a QUIC connection to a vulnerable server
  2. Sending valid QUIC packets from multiple different source addresses to trigger path validation
  3. The server responds by sending path probe packets to validate the new paths
  4. The attacker crafts and sends ACK packets timed to arrive after the server's loss recovery has already declared the corresponding path probe packets as lost
  5. When the server processes these ACKs, it attempts to access the already-removed path probe packet, triggering a nil-pointer dereference and crashing the server
go
// Security patch from sent_packet_handler.go
// Source: https://github.com/quic-go/quic-go/commit/b90058aba5f65f48e0e150c89bbaa21a72dda4de

 		}
 		if p.isPathProbePacket {
 			probePacket := pnSpace.history.RemovePathProbe(p.PacketNumber)
-			if probePacket == nil {
-				panic(fmt.Sprintf("path probe doesn't exist: %d", p.PacketNumber))
+			// the probe packet might already have been declared lost
+			if probePacket != nil {
+				h.ackedPackets = append(h.ackedPackets, probePacket)
 			}
-			h.ackedPackets = append(h.ackedPackets, probePacket)
 			continue
 		}
 		h.ackedPackets = append(h.ackedPackets, p)

Source: GitHub Commit Update

Detection Methods for CVE-2025-29785

Indicators of Compromise

  • Unexpected quic-go server process crashes with panic messages containing "path probe doesn't exist"
  • QUIC server restarts correlating with connections from multiple distinct source IP addresses
  • Log entries showing rapid path validation events followed by service termination
  • Spike in QUIC connection attempts from varying source addresses targeting the same server

Detection Strategies

  • Monitor for Go panic stack traces in application logs mentioning sent_packet_handler.go or path probe operations
  • Implement process monitoring to detect unexpected termination of quic-go based services
  • Deploy network monitoring to identify unusual patterns of QUIC connections from rapidly changing source addresses
  • Enable verbose QUIC logging to track path validation events and correlate with service availability

Monitoring Recommendations

  • Set up alerting for quic-go service process crashes or restarts
  • Monitor network traffic for QUIC connections exhibiting path migration patterns from multiple source addresses in rapid succession
  • Implement health checks for services using quic-go to detect availability issues quickly
  • Review server logs for panic messages related to packet acknowledgment handling

How to Mitigate CVE-2025-29785

Immediate Actions Required

  • Upgrade quic-go to version v0.50.1 or later immediately
  • Review application dependencies to identify all services using the vulnerable quic-go version
  • Consider temporarily disabling path validation features if upgrade is not immediately possible
  • Implement rate limiting on QUIC connections from new source addresses as a temporary measure

Patch Information

The vulnerability is fixed in quic-go version v0.50.1. The patch modifies the ACK handling logic to gracefully handle the case where a path probe packet has already been declared lost. Instead of panicking when the probe packet is not found in the history, the patched code simply skips adding it to the acknowledged packets list and continues processing.

For detailed patch information, see the GitHub Security Advisory GHSA-j972-j939-p2v3 and the GitHub Issue #4981.

Workarounds

  • No official workarounds are available according to the security advisory
  • The only mitigation is upgrading to the patched version v0.50.1
  • If upgrading is not possible, consider deploying network-level protections to limit exposure
  • Implement connection rate limiting at the load balancer level to reduce attack surface
bash
# Update quic-go dependency to patched version
go get github.com/quic-go/quic-go@v0.50.1

# Verify the installed version
go list -m github.com/quic-go/quic-go

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.