Where
-Infinity
0

Vendor Risk Score

See how quic-go compares to other vendors in security performance

View Risk Score →
Severity
4

quic-go is an implementation of the QUIC protocol in Go. An off-path attacker can inject an ICMP Packet Too Large packet. Since affected quic-go versions used IPPMTUDISCDO, the kernel would then return a "message too large" error on sendmsg, i.e. when quic-go attempts to send a packet that exceeds the MTU claimed in that ICMP packet. By setting this value to smaller than 1200 bytes (the minimum MTU for QUIC), the attacker can disrupt a QUIC connection. Crucially, this can be done after completion of the handshake, thereby circumventing any TCP fallback that might be implemented on the application layer (for example, many browsers fall back to HTTP over TCP if they're unable to establish a QUIC connection). The attacker needs to at least know the client's IP and port tuple to mount an attack. This vulnerability is fixed in 0.48.2.

First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Summary

A misbehaving or malicious server can trigger an assertion in a quic-go client (and crash the process) by sending a premature HANDSHAKEDONE frame during the handshake.

Impact

A misbehaving or malicious server can cause a denial-of-service (DoS) attack on the quic-go client by triggering an assertion failure, leading to a process crash. This requires no authentication and can be exploited during the handshake phase. Observed in the wild with certain server implementations (e.g. Solana's Firedancer QUIC).

Affected Versions

- All versions prior to v0.49.1 (for the 0.49 branch) - Versions v0.50.0 to v0.54.0 (inclusive) - Fixed in v0.49.1, v0.54.1, and v0.55.0 onward

Users are recommended to upgrade to the latest patched version in their respective maintenance branch or to v0.55.0 or later.

Details

For a regular 1-RTT handshake, QUIC uses three sets of keys to encrypt / decrypt QUIC packets:

- Initial keys (derived from a static key and the connection ID) - Handshake keys (derived from the client's and server's key shares in the TLS handshake) - 1-RTT keys (derived when the TLS handshake finishes)

On the client side, Initial keys are discarded when the first Handshake packet is sent. Handshake keys are discarded when the server's HANDSHAKEDONE frame is received, as specified in section 4.9.2 of RFC 9001. Crucially, Initial keys are always dropped before Handshake keys in a standard handshake.

Due to packet reordering, it is possible to receive a packet with a higher encryption level before the key for that encryption level has been derived. For example, the server's Handshake packets (containing, among others, the TLS certificate) might arrive before the server's Initial packet (which contains the TLS ServerHello). In that case, the client queues the Handshake packets and decrypts them as soon as it has processed the ServerHello and derived Handshake keys.

After completion of the handshake, Initial and Handshake packets are not needed anymore and will be dropped. quic-go implements an assertion that no packets are queued after completion of the handshake.

A misbehaving or malicious server can trigger this assertion, and thereby cause a panic, by sending a HANDSHAKEDONE frame before actually completing the handshake. In that case, Handshake keys would be dropped before Initial keys.

This can only happen if the server implementation is misbehaving: the server can only complete the handshake after receiving the client's TLS Finished message (which is sent in Handshake packets).

The Fix

quic-go needs to be able to handle misbehaving server implementations, including those that prematurely send a HANDSHAKEDONE frame. We now discard Initial keys when receiving a HANDSHAKEDONE frame, thereby correctly handling premature HANDSHAKEDONE frames. The fix was implemented in https://github.com/quic-go/quic-go/pull/5354.

1 / 3
Source: GitHub
First published (updated )
Severity
4

quic-go is an implementation of the QUIC protocol in Go. In versions prior to 0.49.0, 0.54.1, and 0.55.0, a misbehaving or malicious server can cause a denial-of-service (DoS) attack on the quic-go client by triggering an assertion failure, leading to a process crash. This requires no authentication and can be exploited during the handshake phase. This was observed in the wild with certain server implementations. quic-go needs to be able to handle misbehaving server implementations, including those that prematurely send a HANDSHAKEDONE frame. Versions 0.49.0, 0.54.1, and 0.55.0 discard Initial keys when receiving a HANDSHAKEDONE frame, thereby correctly handling premature HANDSHAKEDONE frames.

First published (updated )
Severity
7

quic-go is an implementation of the QUIC protocol in Go. Prior to version 0.59.1, an attacker can cause excessive memory allocation in quic-go's HTTP/3 client and server implementations by sending a QPACK-encoded HEADERS frame that decodes into a large trailer field section with many unique field names and/or large values. The implementation builds an http.Header for the corresponding http.Request or http.Response, while only enforcing limits on the size of the QPACK-compressed HEADERS frame, not on the decoded field section. This can lead to memory exhaustion. This is very similar to CVE-2025-64702. The difference is that this issue uses HTTP trailers, rather than HTTP headers, as the attack vector. A misbehaving or malicious peer can cause a denial-of-service (DoS) attack against quic-go's HTTP/3 servers or clients by triggering excessive memory allocation, potentially leading to crashes or resource exhaustion. This affects both servers and clients due to symmetric header construction. Version 0.59.1 enforces RFC 9114 decoded field section size limits for trailers as well. It incrementally decodes QPACK entries and checks the field section size after each entry, aborting the stream if an entry causes the limit to be exceeded.

First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Summary An attacker can cause excessive memory consumption in webtransport-go's session implementation by sending a WTCLOSESESSION capsule containing an excessively large Application Error Message. The implementation does not enforce the draft-mandated limit of 1024 bytes on this field, allowing a peer to send an arbitrarily large message payload that is fully read and stored in memory.

This allows an attacker to consume an arbitrary amount of memory. The attacker must transmit the full payload to achieve the memory consumption, but the lack of any upper bound makes large-scale attacks feasible given sufficient bandwidth.

Details WebTransport over HTTP/3, as defined in draft-ietf-webtrans-http3, uses the WTCLOSESESSION capsule to signal session termination with an optional detailed error. The draft specifies that the length of the Application Error Message in this capsule MUST NOT exceed 1024 bytes. In affected versions of webtransport-go, the parser does not enforce this 1024-byte maximum when processing incoming WTCLOSESESSION capsules. A peer can send a capsule with an excessively large payload, forcing the recipient to allocate and buffer the full amount of transmitted data without bound.

The Fix webtransport-go now limits the length of the parsed Application Error Message to 1024 bytes in WTCLOSESESSION capsules by reading no more than this amount. This prevents excessive memory consumption.

1 / 2
Source: GitHub
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Summary An attacker can cause a denial of service in webtransport-go by preventing or indefinitely delaying WebTransport session closure. A malicious peer can withhold QUIC flow control credit on the CONNECT stream, blocking transmission of the WTCLOSESESSION capsule and causing the close operation to hang.

Details WebTransport over HTTP/3 signals session termination by sending a WTCLOSESESSION capsule on the CONNECT stream. The capsule is only needed to transmit a reason phrase and an error code to the peer. After the capsule is sent, the CONNECT stream is closed. In affected versions, the closure procedure blocked indefinitely while waiting for sufficient QUIC flow control credit from the peer. A malicious peer can withhold this credit, preventing the capsule from being sent.

The Fix webtransport-go now attempts to send the WTCLOSESESSION capsule with a short deadline. If the capsule cannot be sent within this deadline, the CONNECT stream is reset instead. This closes the WebTransport session promptly without transmitting the optional error details. This prevents indefinite blocking on session closure.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Summary An attacker can cause unbounded memory consumption repeatedly creating and closing many WebTransport streams. Closed streams were not removed from an internal session map, preventing garbage collection of their resources.

Details webtransport-go maintains an internal map tracking WebTransport streams (both unidirectional and bidirectional) belonging to a session. In affected versions, entries for closed streams were not removed from this map, causing the map to grow indefinitely as streams were created and closed.

A malicious peer can exploit this by opening large numbers of streams and closing them, leading to steady memory growth proportional to the number of closed streams.

The Fix webtransport-go now removes closed streams from the internal map upon closure. This allows the associated resources to be garbage collected, bounding memory usage to active streams only.

1 / 2
Source: GitHub
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Impact

The loss recovery logic for path probe packets that was added in the v0.50.0 release can be used to trigger a nil-pointer dereference by a malicious QUIC client.

In order to do so, the attacker first sends valid QUIC packets from different remote addresses (thereby triggering the newly added path validation logic: the server sends path probe packets), and then sending ACKs for packets received from the server specifically crafted to trigger the nil-pointer dereference.

Patches

v0.50.1 contains a patch that fixes the vulnerability.

This release contains a test that generates random sequences of sent packets (both regular and path probe packets), that was used to verify that the patch actually covers all corner cases.

Workarounds

No.

References

This issue has been reported publicly, but without any context, in https://github.com/quic-go/quic-go/issues/4981.

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203