I did this
Reported-by: Stanislav Fort (Aisle Research)
- Title: HTTP/3 quiche backend drains quiche_h3_recv_body into unbounded recvbuf leading to DoS
- Affected: Builds configured with
--with-quiche; HTTP/3 support when quiche backend is selected (not default in stock builds)
- Trigger: Remote HTTP/3 server streams a large response while the client download (e.g., paused write callback or slow consumer) leaves stream data undispatched
- Root Cause:
h3_data_setup() initializes each stream->recvbuf with BUFQ_OPT_SOFT_LIMIT, so cf_recv_body() repeatedly calls Curl_bufq_slurp() which bypasses the chunk cap, keeps granting MAX_STREAM_DATA, and lets quiche enqueue unlimited data despite the client not draining it
- Vulnerable Code:
// lib/vquic/curl_quiche.c:270-277
Curl_bufq_initp(&stream->recvbuf, &ctx->stream_bufcp,
H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
...
// lib/vquic/curl_quiche.c:431-441
result = Curl_bufq_slurp(&stream->recvbuf,
stream_resp_read, &cb_ctx, &nread);
if(!result && nread)
quiche_h3_conn_dgram_send_flow_control_update(ctx->h3c, ctx->qconn,
stream->id);
- Crash/Vuln Sites:
lib/vquic/curl_quiche.c:cf_recv_body() ← cf_quiche_disp_event() ← cf_process_ingress(); the slurp call allocates recvbuf chunks without bound and continually issues QUIC flow-control credit
- Impact: Remote DoS via memory exhaustion
- Minimal Fix: Stop creating HTTP/3
recvbuf objects with BUFQ_OPT_SOFT_LIMIT so the chunk limit enforces backpressure
- Patch Shape: In
h3_data_setup(), pass 0 for the opts argument of Curl_bufq_initp() (or otherwise reintroduce a hard maximum) so Curl_bufq_slurp() stops once H3_STREAM_RECV_CHUNKS are filled
I expected the following
No response
curl/libcurl version
master
operating system
independent
I did this
Reported-by: Stanislav Fort (Aisle Research)
--with-quiche; HTTP/3 support when quiche backend is selected (not default in stock builds)h3_data_setup()initializes eachstream->recvbufwithBUFQ_OPT_SOFT_LIMIT, socf_recv_body()repeatedly callsCurl_bufq_slurp()which bypasses the chunk cap, keeps grantingMAX_STREAM_DATA, and lets quiche enqueue unlimited data despite the client not draining itlib/vquic/curl_quiche.c:cf_recv_body()←cf_quiche_disp_event()←cf_process_ingress(); the slurp call allocates recvbuf chunks without bound and continually issues QUIC flow-control creditrecvbufobjects withBUFQ_OPT_SOFT_LIMITso the chunk limit enforces backpressureh3_data_setup(), pass0for theoptsargument ofCurl_bufq_initp()(or otherwise reintroduce a hard maximum) soCurl_bufq_slurp()stops onceH3_STREAM_RECV_CHUNKSare filledI expected the following
No response
curl/libcurl version
master
operating system
independent