CVE-2025-43971

GoBGP Panic: The Zero-Byte Assassin

Alon Barad
Alon Barad
Software Engineer

Jan 12, 2026·6 min read

Executive Summary (TL;DR)

GoBGP, a popular BGP implementation, crashes when parsing a specific optional capability in the BGP OPEN message. By setting the 'Software Version' length to zero, an attacker forces a slice bounds out of range panic (data[1:0]). This requires no authentication if the attacker can reach the BGP port, resulting in a complete teardown of BGP sessions and potential routing outages. Fixed in version 3.35.0.

A critical Denial of Service (DoS) vulnerability in GoBGP allows remote attackers to crash the BGP daemon by sending a malformed BGP OPEN message. The crash is triggered by a Go runtime panic due to an improper slice operation when parsing the Software Version capability.

The Hook: When Safety Becomes the Weapon

BGP (Border Gateway Protocol) is the glue holding the internet together. It’s a protocol designed in the 80s on a napkin, and we've been trying to secure it ever since. Enter GoBGP: a modern, open-source implementation written in Go, favored by Software Defined Networking (SDN) folks and cloud architects for its performance and programmability.

But here is the irony: Go is a memory-safe language. It is designed to prevent you from shooting yourself in the foot with buffer overflows. However, when you rely on the runtime to police your memory access, you better handle the errors. If you don't, the runtime steps in like an angry bouncer and shuts the whole party down.

CVE-2025-43971 is exactly that scenario. It isn't a complex ROP chain or a heap feng-shui masterpiece. It is a single, malformed packet that abuses Go's strict bounds checking to trigger a panic, effectively killing the BGP daemon instantly. It’s the digital equivalent of tripping over your own shoelaces, except the consequences are dropped routes and internet outages.

The Flaw: A Vanity Metric Gone Wrong

The vulnerability hides in the parsing logic for RFC 9229, which defines the "BGP Software Version Capability." This is essentially a vanity plate for routers; it allows a BGP speaker to tell its peer, "Hey, I'm running GoBGP v3.0!" during the handshake (OPEN message).

The implementation in pkg/packet/bgp/bgp.go handles this capability. It reads the length of the version string and then tries to slice the byte array to extract that string.

Here is the logic flaw: The code assumes that if a length is provided, it makes sense. It checks if the length is too big (good), and it checks if the buffer has enough bytes (good). But it failed to check if the length provided was 0.

In Go, creating a slice array[low:high] requires that low <= high. If you try to create a slice where the start index is greater than the end index, the Go runtime throws a panic: runtime error: slice bounds out of range. This panic is unrecoverable in the context of the BGP handler, crashing the entire application.

The Code: Slice and Dice (and Crash)

Let's look at the smoking gun in pkg/packet/bgp/bgp.go. The function DecodeFromBytes is responsible for parsing the capability.

// Vulnerable Code
func (c *CapSoftwareVersion) DecodeFromBytes(data []byte) error {
    // ... [checks skipped] ...
    // data[0] is the length of the version string
    softwareVersionLen := uint8(data[0]) 
    
    // Check if we have enough bytes, or if it exceeds 64 chars
    if len(data[1:]) < int(softwareVersionLen) || softwareVersionLen > 64 {
        return NewMessageError(...)
    }
    
    c.SoftwareVersionLen = softwareVersionLen
    
    // THE BUG IS HERE
    // If softwareVersionLen is 0, this becomes data[1:0]
    c.SoftwareVersion = string(data[1:c.SoftwareVersionLen]) 
    return nil
}

When softwareVersionLen is 0:

  1. The buffer data contains at least the length byte (index 0).
  2. The code attempts to slice from index 1 up to 0.
  3. Since 1 > 0, the Go runtime panics immediately.

The fix was embarrassingly simple—just ensure the length isn't zero:

// Patched Code
if len(data[1:]) < int(softwareVersionLen) || softwareVersionLen > 64 || softwareVersionLen == 0 {
    return NewMessageError(...)
}

The Exploit: Killing it with Zero

Exploiting this requires sending a BGP OPEN message. You don't necessarily need a full BGP session established; the crash happens during packet decoding, which occurs very early in the state machine.

Attack Steps:

  1. Connect: Open a TCP connection to port 179 (BGP) on the target.
  2. Handshake: Send a BGP OPEN message.
  3. Payload: Include Optional Parameter Type 2 (Capabilities).
    • Capability Code: 71 (Software Version)
    • Capability Length: 1 (One byte of data follows)
    • Capability Value: \x00 (The version string length is 0)

Because the parsing logic uses the first byte of the value (\x00) as the length of the string to slice, and the string starts at the next byte (offset 1), the math breaks.

The result is binary: The service is up, or the service is dead. There is no middle ground.

The Impact: Silence on the Wire

While this vulnerability scores an 8.6 CVSS (High), the real-world impact depends on where the GoBGP instance sits in your topology.

If this is an internal Route Reflector (RR) or an SDN controller managing your cloud overlay:

  • Total Blackout: The controller crashes, withdrawing all routes it was advertising.
  • Traffic Blackholing: If the data plane relies on this control plane, traffic stops flowing.

If this is an edge router peering with the public internet:

  • Targeted Takedown: An attacker can knock your ASN off the map repeatedly. Watchdogs might restart the service, but the attacker can just send another packet 5 seconds later, creating a flapping route scenario that is arguably worse than a permanent outage due to route dampening penalties by upstream providers.

The Mitigation: Patch or perish

The fix is straightforward. This is a logic error in code, not a protocol flaw.

Primary Mitigation:

  • Upgrade: Move to GoBGP version 3.35.0 or later immediately. The patch includes the bounds check for the zero-length edge case.

Defensive configuration: If you cannot patch immediately (why?), you must ensure that untrusted IP addresses cannot talk to your BGP port (TCP/179).

  • ACLs/Firewalls: Whitelist only known BGP peers. If an attacker cannot complete the TCP handshake, they cannot send the malicious OPEN message.
  • TTL Security (GTSM): Enforcing TTL=255 checks can prevent remote attackers from spoofing packets, though it won't stop a local attacker or a compromised peer.

Fix Analysis (1)

Technical Appendix

CVSS Score
8.6/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H
EPSS Probability
0.03%
Top 93% most exploited

Affected Systems

GoBGP < 3.35.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
GoBGP
OSRG
< 3.35.03.35.0
AttributeDetail
CWE IDCWE-129
Attack VectorNetwork
CVSS Score8.6 (High)
EPSS Score0.00026
ImpactDenial of Service (DoS)
Exploit StatusPoC Available
CWE-129
Improper Validation of Array Index

Improper Validation of Array Index

Vulnerability Timeline

Fix committed to GitHub
2025-02-07
CVE Published
2025-04-21

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.