CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-43971

GoBGP Panic: How a Single Byte Kills the Routing Table

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 21, 2026·5 min read·60 visits

Executive Summary (TL;DR)

GoBGP versions before 3.35.0 crash if they receive a BGP OPEN message with a Software Version Capability length of 0. This is a classic Go slice bounds panic (low > high) exploitable remotely without authentication.

A critical denial-of-service vulnerability in GoBGP allows unauthenticated remote attackers to crash the BGP daemon by sending a malformed OPEN message. The flaw resides in the parsing logic for the Software Version Capability (RFC 9174), where a zero-length field triggers a Go runtime panic due to invalid slice bounds. This results in an immediate teardown of BGP sessions and potential network outages.

The Hook: The Fragile Backbone

BGP (Border Gateway Protocol) is the duct tape holding the internet together. It relies on trust, keepalives, and the assumption that your peer isn't trying to murder your router process. GoBGP has emerged as a modern, high-performance alternative to legacy routing daemons like Quagga or FRR, written in Go to leverage memory safety and concurrency.

But memory safety doesn't mean logic safety. In CVE-2025-43971, we find a vulnerability that is almost poetic in its simplicity. It's not a complex heap overflow or a race condition. It is a simple disagreement between a developer's assumption and the Go runtime's strict rules on slicing. By sending a single byte set to 0x00 inside a specific BGP capability, an attacker can force the GoBGP process to commit suicide via panic(), tearing down all routing sessions instantly.

The Flaw: Logic vs. Runtime

The vulnerability lies in how GoBGP handles RFC 9174, which defines the "Software Version Capability" (Type 71). This capability allows a BGP speaker to tell its peer what software version it's running (mostly for debugging or vanity). The structure is simple: a Type Code, a Length, and a Value string.

In the DecodeFromBytes function within pkg/packet/bgp/bgp.go, the code is responsible for taking the raw bytes of the capability and turning them into a struct. It reads the length byte to determine how long the version string is.

The fatal flaw? The code assumed that if the declared length wasn't too big (over 64 bytes), it was valid. It forgot to check if the length was too small (zero). In the world of C, this might have just resulted in an empty string or a pointer to nothing. In the world of Go, however, messing up slice indices is a capital offense punishable by immediate process termination.

The Code: The Smoking Gun

Let's look at the vulnerable code in pkg/packet/bgp/bgp.go prior to version 3.35.0. The parser takes a byte slice data containing the capability payload.

// Vulnerable Code
softwareVersionLen := uint8(data[0]) // Read the length byte
 
// Check if we have enough data, or if length is absurdly large
if len(data[1:]) < int(softwareVersionLen) || softwareVersionLen > 64 {
    return NewMessageError(...) 
}
 
// THE CRASH SITE
c.SoftwareVersion = string(data[1:c.SoftwareVersionLen])

Here is the logic trap:

  1. An attacker sends a capability where data[0] is 0.
  2. softwareVersionLen becomes 0.
  3. The validation check: len(data[1:]) < 0 is false. The check passes.
  4. The assignment: data[1:0].

In Go syntax slice[low : high], the rule is strict: low must be less than or equal to high. Here, we are asking for a slice starting at index 1 and ending at index 0. This is impossible.

The Result: panic: runtime error: slice bounds out of range [1:0]

The fix was painfully simple: explicitly forbid zero lengths.

- if len(data[1:]) < int(softwareVersionLen) || softwareVersionLen > 64 {
+ if len(data[1:]) < int(softwareVersionLen) || softwareVersionLen > 64 || softwareVersionLen == 0 {

The Exploit: Dropping the Hammer

Exploiting this does not require a complex fuzzing harness. It requires a basic BGP speaker implementation (like a Python script using Scapy or a small Go program). The attack vector is the BGP OPEN message, which is the very first message sent to establish a session.

The Attack Chain:

  1. Connect: Establish a TCP connection to the target GoBGP server on port 179.
  2. Handshake: Construct a BGP OPEN message.
  3. Payload: Insert an Optional Parameter for Capabilities.
  4. The Trigger: Add Capability Type 71 (Software Version). Set the Length field to 0x00.
  5. Send: Fire the packet.

Because this happens during the OPEN phase, the attacker does not need to be fully established or authenticated if the router accepts connections from 0.0.0.0/0 (common in Route Server or public peering scenarios). Even if ACLs are in place, if the attacker can spoof a trusted IP (hard with TCP, but possible) or is a disgruntled peer, they can take down the router with a single packet.

The Impact: Why Panic is Bad

In a web server, a panic might just restart a single goroutine or worker process. In GoBGP, this panic happens in the packet decoding path, often bubbling up to the main loop depending on how the supervisor is configured.

If the GoBGP binary crashes:

  1. Session Drop: All BGP sessions (Peers, Upstreams, Downstreams) are immediately severed.
  2. Route Withdrawal: The router stops advertising prefixes. If this router was a Route Reflector (RR), its clients lose reachability information.
  3. Blackholing: Traffic destined for networks behind this router is dropped until the service restarts and reconverges (which can take minutes for full routing tables).

Since BGP implementations are expected to be robust, this is a high-severity Availability impact (CVSS 8.6).

Official Patches

GoBGP GitHubCommit fixing the off-by-one panic

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.11%
Top 70% most exploited

Affected Systems

GoBGP < 3.35.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
GoBGP
OSRG (Open Source Routing Gym)
< 3.35.03.35.0
AttributeDetail
CWE IDCWE-193 (Off-by-one / Range Error)
CVSS v3.18.6 (High)
Attack VectorNetwork (BGP OPEN Message)
ImpactDenial of Service (DoS)
EPSS Score0.00115 (~30%)
Exploit StatusTrivial PoC possible

MITRE ATT&CK Mapping

T1498Network Denial of Service
Impact
T1190Exploit Public-Facing Application
Initial Access
CWE-193
Off-by-one Error

A product calculates or uses an incorrect maximum or minimum value that is 1 more, or 1 less, than the correct value.

Known Exploits & Detection

N/ANo public exploit script released, but logic is trivial to reproduce.

Vulnerability Timeline

Fix committed to main branch
2025-02-07
CVE Published
2025-04-21
GHSA Advisory Released
2025-04-21

References & Sources

  • [1]GHSA Advisory
  • [2]NVD Detail
  • [3]Go Vulnerability Database

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•26 minutes ago•GHSA-F66Q-9RF6-8795
5.3

GHSA-f66q-9rf6-8795: WebAuthn Re-authentication Freshness Bypass in Flask-Security-Too

An authentication freshness bypass vulnerability exists in the WebAuthn re-authentication path of Flask-Security-Too versions 5.8.0 and 5.8.1. The flaw allows an authenticated attacker to elevate the freshness status of a victim session using their own WebAuthn credential, bypassing re-authentication constraints.

Amit Schendel
Amit Schendel
1 views•5 min read
•about 1 hour ago•CVE-2026-50127
5.9

CVE-2026-50127: Server-Side Request Forgery Bypass via IPv6 Transition Prefixes in Weblate

A Server-Side Request Forgery (SSRF) vulnerability exists in Weblate's private address validator when the VCS_RESTRICT_PRIVATE setting is enabled. By exploiting IPv6 transition mechanisms, such as NAT64, 6to4, or IPv4-compatible configurations, an attacker can bypass private network boundaries and access internal services.

Alon Barad
Alon Barad
3 views•6 min read
•about 1 hour ago•GHSA-P2FR-6HMX-4528
6.4

GHSA-p2fr-6hmx-4528: Unbound Resource Indicators Allow Cross-Audience Access Token Escalation in @better-auth/oauth-provider

A security vulnerability in @better-auth/oauth-provider allows OAuth clients to obtain access tokens for unauthorized audiences due to unbound resource indicators. The implementation fails to bind the requested target resource to the initial authorization grant. Consequently, a client can request an access token targeting any resource server within the global allowlist, bypassing user consent boundaries.

Alon Barad
Alon Barad
3 views•6 min read
•about 2 hours ago•GHSA-86J7-9J95-VPQJ
8.8

GHSA-86J7-9J95-VPQJ: Stored Cross-Site Scripting in Better Auth Plugins via Malicious Redirect URIs

A stored cross-site scripting vulnerability exists in the oidc-provider and mcp plugins of Better Auth. Attackers can register malicious clients with javascript: redirect URIs, leading to origin takeover when users authorize the client.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 3 hours ago•GHSA-9H47-PQCX-HJR4
9.8

GHSA-9H47-PQCX-HJR4: Insecure Cryptographic Defaults in Better Auth OIDC Provider

The Better Auth framework's OIDC provider implementation (oidcProvider) contained insecure cryptographic defaults before version 1.6.11. It advertised the insecure alg=none signing algorithm and accepted plain PKCE challenges by default, leaving downstream clients vulnerable to token signature bypasses and authorization code interception attacks.

Alon Barad
Alon Barad
4 views•6 min read
•about 3 hours ago•GHSA-2VG6-77G8-24MP
3.8

GHSA-2vg6-77g8-24mp: Insufficient Session Expiration via Incomplete Cleanup in Better Auth Ecosystem

A critical session persistence vulnerability exists within the Better Auth framework when configured to use external secondary storage (such as Redis or Cloudflare KV) with default database options. Due to four incomplete user-deletion code paths, active user sessions are not evicted from secondary storage caches during deletion events. As a result, deleted users retain full system access via their pre-existing session cookies until the Session Time-To-Live (TTL) expires.

Amit Schendel
Amit Schendel
4 views•5 min read