chunkloris: kestrel (asp.net core 9, http/3)

part of the chunkloris per-chunk amplification survey. this page is the per-server record for Kestrel (ASP.NET Core 9, HTTP/3) under http/3 data frames over quic.

at a glance

  • server: Kestrel (ASP.NET Core 9, HTTP/3) ASP.NET Core 9.0 + MsQuic
  • runtime: .NET 9
  • ecosystem: dotnet
  • concurrency model: ThreadPool + async/await + System.IO.Pipelines
  • parser: Kestrel HTTP/3 over MsQuic
  • delivery granularity: per-frame
  • chunk-limit helper: none exposed by the framework
  • verdict: per-frame β€” the parser/dispatcher boundary delivers one event per protocol frame (h2 / h3 DATA frame, or ws data frame). cpu cost under paced mode b is measurable per frame.
  • scaling exponent (mode a): 0.98 (wall time vs N, log-log slope across common cells)
  • scaling exponent (mode b): 1.00

measurements

all cells run on a 1-vcpu docker container. cpu cost is derived from the target container’s cgroup v2 cpu.stat usage_usec delta around each cell.

modeNwall (s)server cpu %Β΅s / framebasisok
A-h3-bridge50,0000.11293.82.094server-cpu-cgroupβœ“
A-h3-bridge100,0000.229116.02.661server-cpu-cgroupβœ“
A-h3-bridge250,0000.542106.42.307server-cpu-cgroupβœ“
B-h3-paced-100us50,0007.82057.790.299server-cpu-cgroupβœ“
B-h3-paced-100us100,00015.57644.168.676server-cpu-cgroupβœ“
B-h3-paced-100us250,00039.17743.067.405server-cpu-cgroupβœ“

parser path β€” source citations

  • HTTP/3 support β€” ? β†’ source

what this means

the parser/dispatcher path on this server delivers one event per protocol frame (a http/3 data frames over quic DATA frame or ws frame), so an attacker who sends a request body as N one-byte frames consumes roughly N Γ— (mode-b Β΅s/frame) of server cpu on a single core.

what to do today

  • HTTP/3 quic stream / connection flow control is byte-level; it does not bound DATA frame count.
  • consider a per-stream DATA-frame credit at the h3 dispatcher before delivering payload to the application.

reproducer

the full reproducer for this server is in the paper repo. the docker container pins Kestrel (ASP.NET Core 9, HTTP/3) ASP.NET Core 9.0 + MsQuic and constrains the test container to a single cpu (--cpus=1). the prober script implements mode a (bridge-coalesced) and mode b (paced 100 Β΅s) per the methodology section.

see the draft pdf for the full per-framework discussion.

on this page