VYPR
High severity7.5OSV Advisory· Published Oct 10, 2025· Updated Apr 15, 2026

CVE-2025-59530

CVE-2025-59530

Description

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 HANDSHAKE_DONE frame. Versions 0.49.0, 0.54.1, and 0.55.0 discard Initial keys when receiving a HANDSHAKE_DONE frame, thereby correctly handling premature HANDSHAKE_DONE frames.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/quic-go/quic-goGo
< 0.49.10.49.1
github.com/quic-go/quic-goGo
>= 0.50.0, < 0.54.10.54.1

Affected products

1

Patches

4
275c172fec2b

drop initial packets when the handshake is confirmed

https://github.com/quic-go/quic-goMarten SeemannSep 22, 2025via osv
2 files changed · +5 1
  • connection.go+3 0 modified
    @@ -789,6 +789,9 @@ func (s *connection) handleHandshakeComplete(now time.Time) error {
     }
     
     func (s *connection) handleHandshakeConfirmed(now time.Time) error {
    +	if err := s.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil {
    +		return err
    +	}
     	if err := s.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil {
     		return err
     	}
    
  • connection_test.go+2 1 modified
    @@ -1102,7 +1102,7 @@ func TestConnectionHandshakeServer(t *testing.T) {
     	data, err := (&wire.CryptoFrame{Data: []byte("foobar")}).Append(nil, protocol.Version1)
     	require.NoError(t, err)
     
    -	cs.EXPECT().DiscardInitialKeys()
    +	cs.EXPECT().DiscardInitialKeys().Times(2)
     	tc.connRunner.EXPECT().Retire(gomock.Any())
     	gomock.InOrder(
     		cs.EXPECT().StartHandshake(gomock.Any()),
    @@ -1254,6 +1254,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
     		unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any()).Return(
     			&unpackedPacket{hdr: hdr, encryptionLevel: protocol.Encryption1RTT, data: data}, nil,
     		),
    +		cs.EXPECT().DiscardInitialKeys(),
     		cs.EXPECT().SetHandshakeConfirmed(),
     		tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
     			func(buf *packetBuffer, _ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, error) {
    
0264fbc02e94

drop initial packets when the handshake is confirmed

https://github.com/quic-go/quic-goMarten SeemannSep 22, 2025via osv
2 files changed · +5 1
  • connection.go+3 0 modified
    @@ -845,6 +845,9 @@ func (c *Conn) handleHandshakeComplete(now time.Time) error {
     }
     
     func (c *Conn) handleHandshakeConfirmed(now time.Time) error {
    +	if err := c.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil {
    +		return err
    +	}
     	if err := c.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil {
     		return err
     	}
    
  • connection_test.go+2 1 modified
    @@ -1065,7 +1065,7 @@ func TestConnectionHandshakeServer(t *testing.T) {
     	data, err := (&wire.CryptoFrame{Data: []byte("foobar")}).Append(nil, protocol.Version1)
     	require.NoError(t, err)
     
    -	cs.EXPECT().DiscardInitialKeys()
    +	cs.EXPECT().DiscardInitialKeys().Times(2)
     	gomock.InOrder(
     		cs.EXPECT().StartHandshake(gomock.Any()),
     		cs.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}),
    @@ -1216,6 +1216,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
     		unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any()).Return(
     			&unpackedPacket{hdr: hdr, encryptionLevel: protocol.Encryption1RTT, data: data}, nil,
     		),
    +		cs.EXPECT().DiscardInitialKeys(),
     		cs.EXPECT().SetHandshakeConfirmed(),
     		tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
     			func(buf *packetBuffer, _ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, error) {
    
ce7c9ea8834b

drop initial keys when the handshake is confirmed (#5354)

https://github.com/quic-go/quic-goMarten SeemannOct 3, 2025via ghsa
2 files changed · +9 1
  • connection.go+7 0 modified
    @@ -949,6 +949,13 @@ func (c *Conn) handleHandshakeComplete(now monotime.Time) error {
     }
     
     func (c *Conn) handleHandshakeConfirmed(now monotime.Time) error {
    +	// Drop initial keys.
    +	// On the client side, this should have happened when sending the first Handshake packet,
    +	// but this is not guaranteed if the server misbehaves.
    +	// See CVE-2025-59530 for more details.
    +	if err := c.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil {
    +		return err
    +	}
     	if err := c.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil {
     		return err
     	}
    
  • connection_test.go+2 1 modified
    @@ -1084,7 +1084,7 @@ func TestConnectionHandshakeServer(t *testing.T) {
     	data, err := (&wire.CryptoFrame{Data: []byte("foobar")}).Append(nil, protocol.Version1)
     	require.NoError(t, err)
     
    -	cs.EXPECT().DiscardInitialKeys()
    +	cs.EXPECT().DiscardInitialKeys().Times(2)
     	gomock.InOrder(
     		cs.EXPECT().StartHandshake(gomock.Any()),
     		cs.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}),
    @@ -1235,6 +1235,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
     		unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any()).Return(
     			&unpackedPacket{hdr: hdr, encryptionLevel: protocol.Encryption1RTT, data: data}, nil,
     		),
    +		cs.EXPECT().DiscardInitialKeys(),
     		cs.EXPECT().SetHandshakeConfirmed(),
     		tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
     			func(buf *packetBuffer, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, error) {
    
bc5bccf10fd0

drop initial packets when the handshake is confirmed

https://github.com/quic-go/quic-goMarten SeemannSep 22, 2025via ghsa
2 files changed · +9 1
  • connection.go+7 0 modified
    @@ -949,6 +949,13 @@ func (c *Conn) handleHandshakeComplete(now monotime.Time) error {
     }
     
     func (c *Conn) handleHandshakeConfirmed(now monotime.Time) error {
    +	// Drop initial keys.
    +	// On the client side, this should have happened when sending the first Handshake packet,
    +	// but this is not guaranteed if the server misbehaves.
    +	// See CVE-2025-59530 for more details.
    +	if err := c.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil {
    +		return err
    +	}
     	if err := c.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil {
     		return err
     	}
    
  • connection_test.go+2 1 modified
    @@ -1084,7 +1084,7 @@ func TestConnectionHandshakeServer(t *testing.T) {
     	data, err := (&wire.CryptoFrame{Data: []byte("foobar")}).Append(nil, protocol.Version1)
     	require.NoError(t, err)
     
    -	cs.EXPECT().DiscardInitialKeys()
    +	cs.EXPECT().DiscardInitialKeys().Times(2)
     	gomock.InOrder(
     		cs.EXPECT().StartHandshake(gomock.Any()),
     		cs.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}),
    @@ -1235,6 +1235,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
     		unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any()).Return(
     			&unpackedPacket{hdr: hdr, encryptionLevel: protocol.Encryption1RTT, data: data}, nil,
     		),
    +		cs.EXPECT().DiscardInitialKeys(),
     		cs.EXPECT().SetHandshakeConfirmed(),
     		tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
     			func(buf *packetBuffer, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, error) {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.