Views
No views yet
| 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 |
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 diesAttacker (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 terminatesserverProtocol in read_handshake_response() / read_call_response().1git clone https://github.com/apache/avro.git
2cd avro/lang/py && pip install -e .
3python3 poc_avro_ipc_cwe674.py[+] 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).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 |
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.