Skip to content

Commit 849633a

Browse files
1 parent 37a7182 commit 849633a

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-3c37-wwvx-h642",
4+
"modified": "2026-03-23T20:23:57Z",
5+
"published": "2026-03-23T20:23:57Z",
6+
"aliases": [
7+
"CVE-2026-26209"
8+
],
9+
"summary": "cbor2 has a Denial of Service via Uncontrolled Recursion in cbor2.loads",
10+
"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 (<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.\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.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "PyPI",
21+
"name": "cbor2"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "5.9.0"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 5.8.0"
38+
}
39+
}
40+
],
41+
"references": [
42+
{
43+
"type": "WEB",
44+
"url": "https://github.com/agronholm/cbor2/security/advisories/GHSA-3c37-wwvx-h642"
45+
},
46+
{
47+
"type": "WEB",
48+
"url": "https://github.com/agronholm/cbor2/pull/275"
49+
},
50+
{
51+
"type": "PACKAGE",
52+
"url": "https://github.com/agronholm/cbor2"
53+
},
54+
{
55+
"type": "WEB",
56+
"url": "https://github.com/agronholm/cbor2/releases/tag/5.9.0"
57+
}
58+
],
59+
"database_specific": {
60+
"cwe_ids": [
61+
"CWE-674"
62+
],
63+
"severity": "HIGH",
64+
"github_reviewed": true,
65+
"github_reviewed_at": "2026-03-23T20:23:57Z",
66+
"nvd_published_at": null
67+
}
68+
}

0 commit comments

Comments
 (0)