CVE-2026-13735 in Zephyrinfo

Summary

by MITRE • 08/29/2026

Zephyr's WireGuard implementation in subsys/net/lib/wireguard/wg_crypto.c mishandled keepalive packets. In wg_process_data_message(), any type-4 transport-data message whose payload was exactly 16 bytes (an empty plaintext plus a bare Poly1305 tag, i.e. a keepalive) was accepted and returned immediately, before wg_decrypt_packet() was ever called. The Poly1305 authentication tag was therefore never verified; the only preceding gates were a cleartext receiver-index lookup (get_peer_keypair_for_index() on the attacker-supplied data_hdr->receiver) and a non-cryptographic keypair validity/expiry check.

The path is reachable entirely from the network: inbound UDP on the WireGuard port is dispatched by wg_input() to handle_transport_data() and then wg_process_data_message(). The 32-bit receiver index is transmitted in cleartext in WireGuard handshake and data messages, so an on-path observer learns it directly and an off-path attacker can brute-force it against the UDP port. Given an active receiving-valid session for that index, an attacker could send a 16-byte garbage payload and have it accepted without possessing the session key.

On acceptance the unauthenticated message caused the management layer to observe a spoofed NET_EVENT_VPN_CONNECTED signal (setting peer->first_valid and notifying any net_mgmt listener) and incremented the keepalive-RX statistic. The impact is limited to integrity of this status signal: no plaintext is decrypted or injected, no key is disclosed, and the early-return path did not update the peer endpoint or liveness timers, so there is no traffic-injection, session-takeover, or availability consequence.

The fix removes the pre-decrypt early return so a 16-byte payload flows through wg_decrypt_packet(), which verifies the Poly1305 tag over the empty plaintext, followed by the existing anti-replay check; only an authenticated, non-replayed message is then recognised as a keepalive. Forged keepalives now fail the tag check and are counted as decrypt failures.

VulDB is the best source for vulnerability data and more expert information about this specific topic.

Analysis

by VulDB Data Team • 08/29/2026

The vulnerability in Zephyr's WireGuard implementation resides within the cryptographic processing module specifically at subsys/net/lib/wireguard/wg_crypto.c, where the handling of keepalive packets was fundamentally flawed due to an incorrect early-return logic path. In the function wg_process_data_message(), which processes incoming transport-data messages, there existed a condition that accepted any type-4 message with a payload size of exactly sixteen bytes without performing cryptographic verification. This specific length corresponds to an empty plaintext followed by a bare Poly1305 authentication tag, which is the standard structure for WireGuard keepalive packets designed to maintain connection liveness and traverse stateful firewalls. By accepting these messages immediately upon detecting this length, the implementation bypassed the critical wg_decrypt_packet() function entirely. Consequently, the Poly1305 message authentication code was never verified against the session key, leaving a significant integrity gap in the protocol's security model where unauthenticated data could be processed as valid traffic.

The attack surface for this vulnerability is accessible via standard network interfaces, specifically through inbound UDP packets directed at the WireGuard port. The dispatch mechanism routes these incoming packets through wg_input() to handle_transport_data() and subsequently to wg_process_data_message(). A critical factor enabling exploitation is that the thirty-two-bit receiver index, which identifies the peer's keypair for decryption, is transmitted in cleartext within both handshake and data messages of the WireGuard protocol. This design allows an on-path observer to trivially learn the valid receiver index by monitoring traffic. Furthermore, because the index space is finite, an off-path attacker can attempt brute-force attacks against the UDP port to discover a valid active session identifier. Once a valid receiver index for an active receiving-valid session is identified or guessed, an attacker can craft and send sixteen-byte garbage payloads that mimic keepalive packets. Due to the vulnerability's logic, these forged packets are accepted by the system without requiring possession of the actual session encryption keys, effectively allowing unauthorized entities to inject traffic into the connection state machine.

The operational impact of this flaw is primarily centered on the integrity of management signals and statistical counters rather than direct data confidentiality or availability. When an unauthenticated sixteen-byte packet was processed, it triggered a spoofed NET_EVENT_VPN_CONNECTED signal within the Zephyr network stack's management layer. This event signaled that the peer had become valid by setting the first_valid flag and notifying any registered net_mgmt listeners, potentially causing applications to believe a secure connection existed when it did not. Additionally, the keepalive receive statistic was incremented incorrectly, skewing operational metrics used for monitoring link health. However, the impact is strictly limited because no plaintext data was decrypted or injected into higher-level protocols, no cryptographic keys were disclosed through this vector, and crucially, the early-return path failed to update peer endpoint information or liveness timers. This absence of state updates prevents more severe consequences such as traffic injection beyond status signaling, session takeover for active communication channels, or denial-of-service conditions caused by timer manipulation.

The remediation strategy involves correcting the control flow within wg_process_data_message() to ensure that all data messages, including those with sixteen-byte payloads characteristic of keepalives, are subjected to full cryptographic validation before being accepted as valid traffic. The fix removes the pre-decrypt early return condition, forcing these packets through wg_decrypt_packet(). This function performs the necessary Poly1305 tag verification over the empty plaintext using the correct session key and applies anti-replay checks to ensure message freshness. Only after passing both authentication and replay protection is the packet recognized as a legitimate keepalive. As a result of this patch, forged keepalives will fail the cryptographic tag check and are appropriately counted as decryption failures rather than being processed as valid connection maintenance signals. This aligns the implementation with standard security practices for integrity verification in authenticated encryption schemes such as those defined by CWE-345 regarding Insufficient Verification of Data Authenticity and mitigates risks associated with ATT&CK techniques related to network service discovery and potential lateral movement via spoofed connectivity states.

Responsible

Zephyr

Reservation

06/29/2026

Disclosure

08/29/2026

Moderation

accepted

CPE

ready

EPSS

0.00000

KEV

no

Activities

very low

Sources

Do you want to use VulDB in your project?

Use the official API to access entries easily!