Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-13735

CVE-2026-13735: Zephyr WireGuard Auth Bypass Vulnerability

CVE-2026-13735 is an authentication bypass flaw in Zephyr's WireGuard implementation that allows unauthenticated keepalive packets to be accepted. This post explains the technical details, impact, and mitigation steps.

Updated:

CVE-2026-13735 Overview

CVE-2026-13735 is an authentication bypass vulnerability in the Zephyr real-time operating system's WireGuard implementation. The flaw resides in subsys/net/lib/wireguard/wg_crypto.c, where the function wg_process_data_message() accepts any 16-byte transport-data payload as a keepalive without verifying the Poly1305 authentication tag. A network attacker who knows or brute-forces the cleartext receiver index can inject spoofed keepalive packets against an active session. The impact is limited to integrity of the connection-status signal: the management layer emits a spoofed NET_EVENT_VPN_CONNECTED event and increments the keepalive receive counter. No plaintext is decrypted, no key is disclosed, and no traffic injection or session takeover is possible.

Critical Impact

Unauthenticated attackers on the network can spoof WireGuard keepalive packets, causing the Zephyr VPN management layer to report a false connected state without possessing the session key.

Affected Products

  • Zephyr Project RTOS WireGuard subsystem (subsys/net/lib/wireguard/wg_crypto.c)
  • Zephyr builds shipping the WireGuard implementation prior to commit 87c520a55f0f0e7cd4adf8780166e45eaad6d81c
  • Downstream firmware and embedded devices integrating the vulnerable Zephyr WireGuard stack

Discovery Timeline

  • 2026-08-28 - CVE-2026-13735 published to NVD
  • 2026-09-01 - Last updated in NVD database

Technical Details for CVE-2026-13735

Vulnerability Analysis

The vulnerability is an authentication bypass classified under [CWE-290] (Authentication Bypass by Spoofing). The Zephyr WireGuard receive path dispatches inbound UDP packets from wg_input() to handle_transport_data() and finally to wg_process_data_message(). Before invoking wg_decrypt_packet(), the function short-circuits any type-4 transport-data message whose payload is exactly 16 bytes, treating it as a keepalive.

A legitimate WireGuard keepalive is an empty plaintext protected by a 16-byte Poly1305 tag. The early-return path never validates that tag. The only gates preceding acceptance are a cleartext receiver-index lookup via get_peer_keypair_for_index() and a non-cryptographic keypair validity check.

On acceptance, the management layer notifies net_mgmt listeners with a spoofed NET_EVENT_VPN_CONNECTED event, sets peer->first_valid, and increments the keepalive-RX statistic. The early-return path does not update the peer endpoint or liveness timers, so traffic injection and session takeover are not possible.

Root Cause

The root cause is a size-based fast path that trusts payload length as an implicit authentication signal. The developer optimized keepalive handling by returning before decryption, but Poly1305 tag verification and anti-replay checks live inside wg_decrypt_packet(). Skipping that function removes all cryptographic assurance for the 16-byte case.

Attack Vector

The path is reachable entirely from the network. The 32-bit receiver index is transmitted in cleartext in WireGuard handshake and data messages, so an on-path observer learns it directly. An off-path attacker can brute-force the index against the UDP port. Once a valid index is known and an active receiving session exists, the attacker sends a 16-byte garbage UDP payload and the target accepts it without the session key.

c
	*/
	data_len = net_pkt_get_len(pkt) - sizeof(struct msg_transport_data) - ip_udp_hdr_len;

-	/* If the data_len is 16 bytes (padded length), then it is a keepalive message */
-	if (data_len == 16U) {
-		/* keep-alive message */
-		NET_DBG("Keepalive message received from %s",
-			net_sprint_addr(addr->sa_family,
-					(const void *)&net_sin(addr)->sin_addr));
-		vpn_stats_update_keepalive_rx(ctx);
-
-		if (!peer->first_valid) {
-			net_mgmt_event_notify(NET_EVENT_VPN_CONNECTED, peer->iface);
-			peer->first_valid = true;
-		}
-
-		return 0;
-	}
+	/* A 16-byte payload (empty plaintext + Poly1305 tag) is a keepalive
+	 * message. It must still be authenticated and replay-checked below
+	 * before it is acted upon, so it flows through the normal decrypt path
+	 * just like any other transport-data message.
+	 */

Source: Zephyr commit 87c520a5. The patch removes the pre-decrypt early return so 16-byte payloads flow through wg_decrypt_packet(), which verifies the Poly1305 tag and applies the anti-replay window.

Detection Methods for CVE-2026-13735

Indicators of Compromise

  • Unexpected NET_EVENT_VPN_CONNECTED events on Zephyr devices when no legitimate handshake or reconnection occurred.
  • Abnormal growth in the WireGuard keepalive-RX statistic relative to the peer's traffic profile.
  • Inbound 16-byte WireGuard transport-data UDP packets from source addresses that do not match the known peer endpoint.

Detection Strategies

  • Inspect Zephyr device logs and net_mgmt event streams for repeated VPN connection notifications tied to a single peer index.
  • Correlate WireGuard UDP port traffic captures against expected peer endpoints and flag 16-byte payloads originating from unrecognized IPs.
  • Compare firmware build hashes and Zephyr revisions against the patched commit 87c520a5 across the device fleet.

Monitoring Recommendations

  • Enable verbose network statistics on Zephyr WireGuard peers and export keepalive-RX counters to a centralized telemetry pipeline.
  • Alert on receiver-index scanning behavior: high-volume 16-byte UDP payloads to the WireGuard port from a single source.
  • Track VPN connection-state transitions per device and investigate flapping or duplicate connect events.

How to Mitigate CVE-2026-13735

Immediate Actions Required

  • Update Zephyr-based firmware to a build containing commit 87c520a55f0f0e7cd4adf8780166e45eaad6d81c or later.
  • Inventory all embedded devices running Zephyr with the WireGuard subsystem enabled and prioritize patching internet-exposed nodes.
  • Review VPN connection-state alerting logic in downstream applications that trust NET_EVENT_VPN_CONNECTED as an authenticated signal.

Patch Information

The fix is available in the Zephyr project at commit 87c520a5 and documented in GHSA-xxrw-r78f-f6mx. The patch removes the pre-decrypt early return so that 16-byte transport-data messages flow through wg_decrypt_packet(). Poly1305 tag verification and anti-replay checks then run on every keepalive. Forged keepalives fail the tag check and increment the decrypt-failure counter.

Workarounds

  • Restrict inbound UDP access to the WireGuard port using upstream firewall rules that allow only known peer source addresses.
  • Disable or gate any application logic that treats NET_EVENT_VPN_CONNECTED as proof of an authenticated peer until firmware is patched.
  • Rotate WireGuard peer keys after patching to invalidate any receiver indices that may have been observed during the vulnerable window.
bash
# Verify Zephyr WireGuard fix is present in your source tree
cd zephyr
git log --oneline subsys/net/lib/wireguard/wg_crypto.c | grep 87c520a5
# If empty, cherry-pick the fix:
git cherry-pick 87c520a55f0f0e7cd4adf8780166e45eaad6d81c
west build -b <your_board> -p auto samples/net/wireguard

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.