# orbax-checkpoint CWE-674 PoC ![Severity: HIGH](https://img.shields.io/badge/Severity-HIGH-red) ![CWE-674](https://img.shields.io/badge/CWE-674-orange) ![CVSS 7.5](https://img.shields.io/badge/CVSS-7.5-red) ![Status: SUBMITTED](https://img.shields.io/badge/Status-SUBMITTED-blue) ## Target | Field | Value | |---|---| | Package | orbax-checkpoint | | Version | 0.11.40 (latest) | | Commit | a87ebc8 | | Platform | huntr.com | | CWE | CWE-674 Uncontrolled Recursion | | CVSS | 7.5 High | ## Root Cause `_unchunk_array_leaves_in_place(d)` in `orbax/checkpoint/msgpack_utils.py` recursively traverses a dict deserialized from a msgpack checkpoint file with no depth guard. A 1,001-level nested dict (3,009 bytes) triggers RecursionError. ```python def _unchunk_array_leaves_in_place(d): # no depth guard for k, v in d.items(): elif isinstance(v, dict): _unchunk_array_leaves_in_place(v) # ← unbounded recursion ``` ## Trigger Path ``` victim: checkpointer.restore(malicious_dir/) → MsgpackHandler.deserialize(dir/checkpoint) → msgpack_restore(bytes) → _unchunk_array_leaves_in_place(state_dict) ← RecursionError at depth 1001 ``` ## Reproduce ```bash pip install orbax-checkpoint msgpack python3 poc_orbax.py ``` Expected output: ``` [*] Python recursion limit: 1000 [*] Payload: 3009 bytes, depth=1001 [+] CONFIRMED: RecursionError in _unchunk_array_leaves_in_place [+] CONFIRMED via MsgpackHandler: maximum recursion depth exceeded ``` ## Fix ```python def _unchunk_array_leaves_in_place(d, _depth=0): if _depth > 500: raise ValueError('Checkpoint nesting depth exceeds limit') ... _unchunk_array_leaves_in_place(v, _depth + 1) ``` ## Files | File | Purpose | |---|---| | `poc_orbax.py` | Working PoC | | `submission.md` | Full technical writeup (markdown) | | `report.md` | Plain-prose paste target for huntr form | | `poc-evidence.html` | HTML evidence page with terminal output | | `README.md` | This file |