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-2026-26014

Pion DTLS & The Birthday Paradox: How Random Nonces Broke AES-GCM

Alon Barad
Alon Barad
Software Engineer

Feb 12, 2026·6 min read·52 visits

Executive Summary (TL;DR)

Pion DTLS used random numbers for AES-GCM nonces instead of counters. Due to the Birthday Paradox, this leads to collisions in long sessions. A collision breaks AES-GCM security completely (key recovery + forgery). Fixed in v3.1.0 by using sequence numbers.

A fundamental cryptographic flaw in Pion DTLS (versions prior to v3.1.0) exposes AES-GCM encrypted sessions to the 'Forbidden Attack' (nonce reuse). By relying on random values for the explicit nonce rather than a strict counter, the library falls victim to the Birthday Paradox. In high-volume sessions, this guarantees a nonce collision, allowing attackers to recover the authentication key, forge packets, and potentially decrypt traffic.

The Gopher in the Room

If you are building a WebRTC application in Go, you are almost certainly using Pion. It is the gold standard, the heavy lifter, the 'Gopher in the room' for real-time communication. From cloud gaming to suspicious video chat apps, Pion handles the handshake and the transport.

But here is the thing about DTLS (Datagram Transport Layer Security): it is just TLS over UDP. And UDP means packets get lost, reordered, or duplicated. This makes the cryptographic state machine a nightmare to manage compared to the nice, orderly stream of TCP. Developers often take shortcuts to handle this chaos.

In CVE-2026-26014, the shortcut was randomness. Specifically, how the library generated the 'nonce' (number used once) for AES-GCM encryption. The developers trusted crypto/rand to keep them safe. It is a common mistake: assuming that if a number is random enough and big enough, it will never repeat. Spoiler alert: Probability theory hates your assumptions.

Math is a Harsh Mistress (The Flaw)

Let's talk about AES-GCM. It is an AEAD (Authenticated Encryption with Associated Data) cipher. It requires a unique nonce for every single invocation with the same key. If you reuse a nonce, even once, the security guarantees of GCM collapse faster than a house of cards in a hurricane.

The DTLS 1.2 spec (RFC 5288) defines the GCM nonce as 12 bytes: 4 bytes of fixed 'salt' and 8 bytes of 'explicit' nonce sent with the packet. Pion implemented the explicit part by generating 8 random bytes.

Here is where the Birthday Paradox walks in and slaps you. You might think 64 bits (8 bytes) of randomness is massive. But the probability of a collision scales with the square root of the space size. With $2^{64}$ possibilities, you reach a 50% chance of collision after roughly $2^{32}$ packets (about 4.2 billion).

> [!WARNING] > Wait, 4 billion packets? > That sounds like a lot, but in a high-bandwidth WebRTC video stream running 24/7 (like a security camera or a dedicated media server), hitting this number is not just possible; it is inevitable.

Once a collision occurs, an attacker observing the traffic sees two different packets encrypted with the same Key and Nonce. This is the cryptographic equivalent of dividing by zero.

The Smoking Gun (Code Analysis)

Let's look at the code. This is where the 'random' decision was made. The developers likely chose this because tracking state in a UDP protocol is annoying—you have to handle sliding windows and out-of-order delivery.

The Vulnerable Code (Before v3.1.0):

// Inside the encryption routine
// explicitNonce is the 8-byte field
if _, err := rand.Read(explicitNonce); err != nil {
    return nil, err
}
// ... Encrypt using this random nonce ...

That rand.Read call is the fatal flaw. It is stateless. It does not know what it generated five milliseconds ago.

The Fix (Commit 61762dee8217991882c5eb79856b9e7a73ee349f):

The fix aligns Pion with RFC 9325, which mandates deterministic nonces based on the record sequence number. Since DTLS already tracks sequence numbers to prevent replay attacks, we can just use that.

// The new way: Deterministic Construction
// nonce[4:] is the 8-byte explicit part
 
// We combine the Epoch (2 bytes) and Sequence Number (6 bytes)
// to guarantee uniqueness for the life of the session.
seq64 := (uint64(pkt.Header.Epoch) << 48) | (pkt.Header.SequenceNumber & 0x0000ffffffffffff)
 
binary.BigEndian.PutUint64(nonce[4:], seq64)

This change is beautiful in its simplicity. Epoch increments on re-handshake, and SequenceNumber increments on every packet. It is mathematically impossible to repeat a nonce unless the sequence number wraps around (which takes eons) or the implementation is broken elsewhere.

Joux's Forbidden Dance (Exploitation)

So, how do we weaponize this? We use Joux's Attack (the 'Forbidden Attack'). This is not a theoretical 'maybe we can decrypt one byte' attack. This is a 'we own the session' attack.

The Attack Chain

  1. The Campout: We position ourselves as a Man-in-the-Middle (MITM) or a passive observer recording a high-value, long-duration stream (e.g., a corporate conference bridge).
  2. The Hunt: We parse the DTLS headers, specifically looking at the 8-byte explicit nonce field. We store these in a hash table.
  3. The Collision: Eventually, the Birthday Paradox pays off. We find Packet A and Packet B. Different content, same nonce.
  4. The Math:
    • In GCM, Ciphertext = Plaintext XOR Keystream.
    • Since the Key and Nonce are the same, the Keystream is the same.
    • C1 XOR C2 = P1 XOR P2. We now know the XOR difference of the plaintexts. If the content is predictable (like standard RTP headers), we can recover the Keystream.
  5. The Kill (GHASH Recovery): This is the real danger. GCM uses a polynomial MAC (GHASH) for authentication. With two messages using the same nonce, we can set up a polynomial equation where the only unknown is the authentication key, $H$. Solving this equation gives us $H$.

Once we have $H$, we can forge valid authentication tags for any ciphertext. We can inject malicious video frames, terminate the session, or impersonate the server. We have effectively broken the integrity of the connection.

The Fallout & Cleanup

While the CVSS score is a moderate 5.9 (due to the high attack complexity—monitoring 4 billion packets takes time), the impact is catastrophic for affected sessions. For standard web browsing, this is negligible. for infrastructure-grade WebRTC (telehealth, surveillance, industrial control), it is a ticking time bomb.

Mitigation Strategy

  1. Upgrade Immediately: If you are using github.com/pion/dtls, check your go.mod. If it says anything less than v3.1.0, you are vulnerable. go get github.com/pion/dtls/v3@v3.1.0.
  2. Force Re-keying: If you cannot upgrade immediately, configure your application to force a DTLS re-handshake frequently (e.g., every 1 million packets or every hour). This resets the encryption keys before the probability of a nonce collision becomes statistically significant.
  3. Audit Your Crypto: This serves as a stark reminder: Never implement your own nonce logic. If a protocol spec says 'use a counter', use a counter. If it says 'use random', ask 'why not a counter?'. Randomness is not a security strategy; it is a desperate hope that the universe is big enough to hide your mistakes.

Official Patches

PionPull Request #796 fixing the nonce generation

Fix Analysis (1)

Technical Appendix

CVSS Score
5.9/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

Affected Systems

Pion DTLS (Go implementation)WebRTC Applications using PionStreaming Servers (Go-based)VoIP Services using Pion

Affected Versions Detail

Product
Affected Versions
Fixed Version
Pion DTLS
Pion
>= 1.0.0, < 3.1.03.1.0
AttributeDetail
CWE IDCWE-327
Attack VectorNetwork (Passive/MITM)
CVSS v3.15.9 (Medium)
ImpactKey Recovery & Forgery
Key CipherAES-GCM
Collision Bound~2^32 Packets

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1040Network Sniffing
Credential Access
CWE-327
Broken Crypto Algorithm

Use of a Broken or Risky Cryptographic Algorithm

Known Exploits & Detection

TheoreticalJoux's Forbidden Attack on AES-GCM (Standard Cryptographic Attack)

Vulnerability Timeline

Fix PR #796 Merged
2026-02-10
Advisory Published
2026-02-11

References & Sources

  • [1]GitHub Advisory
  • [2]RFC 9325: Secure Use of TLS and DTLS

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

•less than a minute ago•CVE-2026-49471
8.3

CVE-2026-49471: Unauthenticated Remote Code Execution in Serena MCP Toolkit via DNS Rebinding and Memory Poisoning

CVE-2026-49471 is a high-severity security vulnerability in Serena, an AI-assisted coding Model Context Protocol (MCP) toolkit. In versions prior to v1.5.2, Serena's built-in web dashboard exposes an unauthenticated Flask API on a predictable port. Lacking host validation and CSRF protections, this endpoint is vulnerable to DNS Rebinding. An attacker can lure a user to a malicious webpage, bypass the Same-Origin Policy (SOP), rewrite the AI agent's persistent memory, and execute arbitrary commands on the host operating system via the autonomous agent's shell execution engine.

Alon Barad
Alon Barad
0 views•5 min read
•29 minutes ago•GHSA-MXWC-WH95-PW4G
5.3

GHSA-MXWC-WH95-PW4G: Denial of Service via Uncontrolled Recursion in Trapster DNS Parser

The trapster honeypot package is vulnerable to a remote denial of service (DoS) vulnerability due to uncontrolled recursion during the parsing of malformed DNS compression pointers in the decode_labels function.

Amit Schendel
Amit Schendel
1 views•6 min read
•about 1 hour ago•GHSA-Q95X-7G78-RCCV
6.3

GHSA-Q95X-7G78-RCCV: Safe Rust Memory Corruption via Use-After-Free in oneringbuf Crate

A critical Use-After-Free (UAF) memory corruption vulnerability exists in the oneringbuf Rust crate prior to version 0.8.0. The vulnerability allows safe Rust code to instantiate and clone reference wrappers that point to heap-allocated ring buffers. Dropping one wrapper prematurely reclaims the backing memory, leading to dangling pointer references and subsequent Use-After-Free or Double Free states.

Amit Schendel
Amit Schendel
2 views•7 min read
•about 14 hours ago•CVE-2026-53359
8.8

CVE-2026-53359: Use-After-Free in Linux Kernel KVM Shadow MMU (Januscape)

Januscape (CVE-2026-53359) is a critical Use-After-Free vulnerability in the x86 Shadow MMU component of the Linux Kernel's KVM subsystem. A logic error in shadow page tracking permits unauthorized page reuse without validating architectural execution roles, leading to dangling pointers in reverse mapping (rmap) tracking entries during guest memory teardown.

Amit Schendel
Amit Schendel
67 views•5 min read
•about 14 hours ago•CVE-2026-48282
10.0

CVE-2026-48282: Unauthenticated Path Traversal and Arbitrary File Write in Adobe ColdFusion Remote Development Services

CVE-2026-48282 is a critical unauthenticated path traversal and arbitrary file write vulnerability in the Remote Development Services (RDS) component of Adobe ColdFusion. The vulnerability allows a remote, unauthenticated attacker to bypass directory boundaries and write arbitrary files, including CFML-based web shells, onto the host server. This flaw is actively exploited in the wild and enables full unauthenticated remote code execution under the privileges of the ColdFusion service account.

Alon Barad
Alon Barad
23 views•6 min read
•about 19 hours ago•GHSA-GQ4G-FPC9-VJFQ
2.3

GHSA-gq4g-fpc9-vjfq: Username Enumeration via Predictable Decoy Credentials in web-auth/webauthn-lib

An information disclosure vulnerability exists in the web-auth/webauthn-lib PHP library when using the default SimpleFakeCredentialGenerator without a configured secret. This allows unauthenticated remote attackers to determine if a username exists on the target application.

Alon Barad
Alon Barad
8 views•5 min read