{"id":"GHSA-3c37-wwvx-h642","summary":"cbor2 has a Denial of Service via Uncontrolled Recursion in cbor2.loads","details":"### Summary\n\n- The `cbor2` library is vulnerable to a Denial of Service (DoS) attack caused by uncontrolled recursion when decoding deeply nested CBOR structures.\n- 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.\n- 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`.\n- By sending a stream of small (\u003c100KB) malicious packets, an attacker can repeatedly crash worker processes faster than they can be restarted, resulting in a complete and sustained Denial of Service.\n\n### Details\n\n- The vulnerability stems from the recursive design of the `CBORDecoder` class, specifically how it decodes nested container types like Arrays and Maps.\n- 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.\n- Vulnerable Code Locations:\n  - `cbor2/decoder.py` (Pure Python implementation)\n  - `source/decoder.c` (C extension implementation)\n- Execution Flow:\n  1. The `cbor2.loads()` function initializes a `CBORDecoder` and calls its `decode()` method.\n  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`.\n  3. `decode_array` loops and calls `self.decode()` for each item, leading to deep recursion when parsing a payload like `[...[...[1]...]...]`.\n\n### PoC\n\n```\nimport cbor2\n\nDEPTH = 1000\n\npayload = b'\\x81' * DEPTH + b'\\x01'\nprint(f\"[*] Payload size: {len(payload) / 1024:.2f} KB\")\nprint(\"[*] Triggering decoder...\")\n\ntry:\n    cbor2.loads(payload)\n    print(\"[+] Parsed successfully (Not Vulnerable)\")\nexcept RecursionError:\n    print(\"\\n[!] VULNERABLE: RecursionError triggered!\")\nexcept Exception as e:\n    print(f\"\\n[-] Unexpected Error: {type(e).__name__}: {e}\")\n```\n\n### Impact\n\n- 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).\n- 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.\n\n### Credit\n\nThis issue was discovered by Kevin Tu of TMIR at ByteDance. The patch was developed by @agronholm.","aliases":["CVE-2026-26209","PYSEC-2026-2123"],"modified":"2026-09-10T03:50:36.691215585Z","published":"2026-03-23T20:23:57Z","database_specific":{"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-03-23T20:23:57Z","nvd_published_at":"2026-03-23T19:16:39Z","cwe_ids":["CWE-674"]},"references":[{"type":"WEB","url":"https://github.com/agronholm/cbor2/security/advisories/GHSA-3c37-wwvx-h642"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-26209"},{"type":"WEB","url":"https://github.com/agronholm/cbor2/pull/275"},{"type":"WEB","url":"https://github.com/agronholm/cbor2/commit/e61a5f365ba610d5907a0ae1bc72769bba34294b"},{"type":"PACKAGE","url":"https://github.com/agronholm/cbor2"},{"type":"WEB","url":"https://github.com/agronholm/cbor2/releases/tag/5.9.0"}],"affected":[{"package":{"name":"cbor2","ecosystem":"PyPI","purl":"pkg:pypi/cbor2"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"5.9.0"}]}],"versions":["1.0.0","1.1.0","2.0.0","3.0.0","3.0.1","3.0.2","3.0.3","3.0.4","4.0.0","4.0.1","4.1.0","4.1.1","4.1.2","5.0.0","5.0.1","5.1.0","5.1.1","5.1.2","5.2.0","5.2.0.post1","5.3.0","5.4.0","5.4.1","5.4.2","5.4.2.post1","5.4.3","5.4.4","5.4.5","5.4.6","5.5.0","5.5.1","5.6.0","5.6.1","5.6.2","5.6.3","5.6.4","5.6.5","5.7.0","5.7.1","5.8.0"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-3c37-wwvx-h642/GHSA-3c37-wwvx-h642.json","last_known_affected_version_range":"\u003c= 5.8.0"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}]}