Skip to main content
VulnerabilityPublished Updated

CVE-2026-26209: Esphome · cbor2 has a Denial of Service via Uncontrolled Recursion in cbor2.loads

Affects esphomeSource GCVE Database

0
Compare
Authoritative record:CVE-2026-26209· High 7.5

Not known to be exploited · CVSS 7.5 High : upgrade to 2026.3.1 soon.

Data as of 30 Oct 2026, 07:30 UTC

CVSS 3.0 base score
7.5High
How severe the flaw is on the 0–10 CVSS scale.
Patch
Available – fixed in 2026.3.1
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Exploitation evidence

  1. Disclosed: evidence found.

    CVE published 23 Mar 2026

  2. Detectable: no evidence on record.

    No public nuclei template indexed

  3. Weaponized: no evidence on record.

    No public exploit code indexed in Metasploit or Exploit-DB

  4. Exploited in the wild: no evidence on record.

    Not in CISA KEV and no source reports exploitation

  5. Observed by OffSeq Mirage: no evidence on record.

    No attack traffic recorded by OffSeq Mirage sensors

A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), the Metasploit, Exploit-DB and nuclei-templates index as of 29 Oct 2026.

What to do

Upgrade esphome to 2026.3.1.

Affected software

ProductAffectedFixed in
Homebrewesphomepkg:brew/esphomeOther threatsAffected
  • >=2026.3.0 <2026.3.1
Fixed in
  • 2026.3.1

Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.

Description

### Summary - The `cbor2` library is vulnerable to a Denial of Service (DoS) attack caused by uncontrolled recursion when decoding deeply nested CBOR structures. - This vulnerability affects both the pure Python implementation and the C extension (`_cbor2`). The C extension correctly uses Python's C-API for recursion protection (`Py_EnterRecursiveCall`), but this mechanism is designed to prevent a stack overflow by raising a `RecursionError`. In some environments, this exception is not caught, thus causing the service process to terminate. - While the library handles moderate nesting, it lacks a configurable, data-driven depth limit independent of Python's global recursion setting. An attacker can supply a crafted CBOR payload containing thousands of nested arrays (e.g., `0x81`). When `cbor2.loads()` attempts to parse this, it hits the interpreter's recursion limit, causing the call to raise a `RecursionError`. - By sending a stream of small (<100KB) malicious packets, an attacker can repeatedly crash worker processes faster than they can be restarted, resulting in a complete and sustained Denial of Service. ### Details - The vulnerability stems from the recursive design of the `CBORDecoder` class, specifically how it decodes nested container types like Arrays and Maps. - Inside `decode_array` (and similarly `decode_map`), the decoder iterates through the number of elements specified in the CBOR header. For each element, it calls `self.decode()` again to parse the nested item. This recursive call lacks a depth-tracking mechanism. - Vulnerable Code Locations: - `cbor2/decoder.py` (Pure Python implementation) - `source/decoder.c` (C extension implementation) - Execution Flow: 1. The `cbor2.loads()` function initializes a `CBORDecoder` and calls its `decode()` method. 2. The `decode()` method reads the initial byte and dispatches control to a specific handler based on the major type. For an Array (Major Type 4), it calls `decode_array`. 3. `decode_array` loops and calls `self.decode()` for each item, leading to deep recursion when parsing a payload like `[...[...[1]...]...]`. ### PoC ``` import cbor2 DEPTH = 1000 payload = b'\x81' * DEPTH + b'\x01' print(f"[*] Payload size: {len(payload) / 1024:.2f} KB") print("[*] Triggering decoder...") try: cbor2.loads(payload) print("[+] Parsed successfully (Not Vulnerable)") except RecursionError: print("\n[!] VULNERABLE: RecursionError triggered!") except Exception as e: print(f"\n[-] Unexpected Error: {type(e).__name__}: {e}") ``` ### Impact - Scope: This vulnerability affects any application using `cbor2` to parse untrusted data. Common use cases include IoT data processing, WebAuthn (FIDO2) authentication flows, and inter-service communication over COSE (CBOR Object Signing and Encryption). - Attack Vector: A remote, unauthenticated attacker can achieve a full Denial of Service with a highly efficient, low-bandwidth attack. A payload under 100KB is sufficient to reliably terminate a Python worker process. ### Credit This issue was discovered by Kevin Tu of TMIR at ByteDance. The patch was developed by @agronholm.

References

Community reviews

Loading reviews…