GoBGP Panic: The Zero-Byte Assassin
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:
- The buffer
datacontains at least the length byte (index 0). - The code attempts to slice from index
1up to0. - 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:
- Connect: Open a TCP connection to port 179 (BGP) on the target.
- Handshake: Send a BGP OPEN message.
- 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)
- Capability Code:
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.
Official Patches
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:HAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
GoBGP OSRG | < 3.35.0 | 3.35.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-129 |
| Attack Vector | Network |
| CVSS Score | 8.6 (High) |
| EPSS Score | 0.00026 |
| Impact | Denial of Service (DoS) |
| Exploit Status | PoC Available |
MITRE ATT&CK Mapping
Improper Validation of Array Index
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.