Downloads · 30 days
0
ericblackgachara/apache-avro-cwe674-ipc-poc
apache-avro-cwe674-ipc-poc is a machine learning model from ericblackgachara. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
Downloads · 30 days
0
Access
Public
Updated Jun 3, 2026
Repo size
212 KB
Likes
0
Public
Click a slice to open those files.
.pdf106 KB · 79%
From the Hugging Face model README
| Field | Value |
|---|---|
| Target | apache/avro Python library (IPC layer) |
| Platform | huntr.com |
| Commit | bd70a0859b9d739aad0547aa61bd17291049773b |
| Severity | High (7.5) |
| CWE | CWE-674 Uncontrolled Recursion |
| Attack Vector | Network, unauthenticated, bidirectional |
| Est. payout | $1,500 |
The Avro IPC handshake exchanges protocol declarations as JSON. Both the server (clientProtocol) and client (serverProtocol) parse the peer's protocol with avro.protocol.parse(), which recurses once per nested type level with no depth limit. A type nested ~1005 deep raises RecursionError. On the server this fires inside Responder.respond(), whose only guard is except avro.errors.AvroException — and RecursionError is a RuntimeError, so it escapes and crashes the worker.
ipc.py process_handshake() -> avro.protocol.parse(client_protocol) # attacker bytes
protocol.py parse() -> make_avpr_object() -> _parse_response()
schema.py make_avsc_object() ← recurses per nesting level, no cap → RecursionError
ipc.py respond() except avro.errors.AvroException ← does NOT catch RecursionError
→ worker thread/process dies
Attacker (client) ──HandshakeRequest{clientProtocol: array nested ×1005}──▶ Server
Server: Responder.respond()
└─ process_handshake()
└─ avro.protocol.parse(client_protocol)
└─ make_avsc_object() × 1005 → RecursionError
└─ except avro.errors.AvroException → NOT matched (RuntimeError)
→ exception escapes respond() → connection worker terminates
Bidirectional: a malicious server crashes Python clients the same way via serverProtocol in read_handshake_response() / read_call_response().
git clone https://github.com/apache/avro.git
cd avro/lang/py && pip install -e .
python3 poc_avro_ipc_cwe674.py
Expected output:
[+] Malicious protocol JSON : 28,250 bytes
[+] Nesting depth : 1005
DEMO 1: End-to-end server crash via Responder.respond()
[+] Framed handshake call_request: 28,287 bytes
[+] CONFIRMED: RecursionError escaped respond()
DEMO 2: Client crash via malicious serverProtocol
[+] CONFIRMED: RecursionError - a malicious server crashes its clients.
DEMO 1 drives the genuine Responder.respond() handler with a wire-format HandshakeRequest — a real server-thread crash, not a simulation.
_depth counter through make_avsc_object() and raise SchemaParseException (an AvroException the IPC layer handles) past a cap (e.g. 200).respond()'s guard to except (avro.errors.AvroException, RecursionError).The depth limit also closes the file-load recursion path (DataFileReader parsing an embedded schema).
| File | Description |
|---|---|
poc_avro_ipc_cwe674.py | Working PoC — end-to-end respond() crash + client-side demo |
submission.md | Full technical writeup (markdown, keep permanently) |
report.md | Plain prose only — paste into huntr form field |
poc-evidence.html | Self-contained HTML evidence page for attachment |
README.md | This file |
This is a separate bug, separate folder from the CWE-789 read_array allocation bug (apache-avro-poc/) and the CWE-400 varint O(N²) bug (apache-avro-varint-cwe400-poc/). Distinct root cause (recursion in the protocol/schema parser), distinct attack surface (network IPC handshake vs. file load), and the highest-impact delivery path of the set.