YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

apache/avro Python β€” CWE-674 IPC Handshake Recursion (Unauthenticated Network DoS)

SEVERITY: HIGH 7.5 CWE-674 VECTOR: NETWORK UNAUTH STATUS: READY TO SUBMIT

Target Info

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

Root Cause

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

Trigger Path

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().

Reproduction

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.

Suggested Fix

  1. Depth-limit the parser: thread a _depth counter through make_avsc_object() and raise SchemaParseException (an AvroException the IPC layer handles) past a cap (e.g. 200).
  2. Harden the handler: broaden respond()'s guard to except (avro.errors.AvroException, RecursionError).

The depth limit also closes the file-load recursion path (DataFileReader parsing an embedded schema).

Files

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

Relationship to Other Avro Findings

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.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support