chunkloris: spring boot + tomcat (h2c)

part of the chunkloris per-chunk amplification survey. this page is the per-server record for Spring Boot + Tomcat (h2c) under http/2 (h2c) data frames.

at a glance

  • server: Spring Boot + Tomcat (h2c) spring-boot-3.3.5 / tomcat-10.1
  • runtime: JDK 21
  • ecosystem: jvm
  • concurrency model: thread-pool
  • parser: Tomcat HTTP/2 parser
  • delivery granularity: per-frame
  • chunk-limit helper: none exposed by the framework
  • verdict: h2 GOAWAY 11 (ENHANCE_YOUR_CALM) β€” the server aborts the tiny-frame request before consuming the target body. this is the cleanest in-protocol mitigation we observed, but it is not a spec requirement, and it is specific to http/2.

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-h2-bridge50,0000.0022221.2β€”server-cpu-cgroupβœ—
A-h2-bridge100,0000.0021639.2β€”server-cpu-cgroupβœ—
A-h2-bridge250,0000.0021734.7β€”server-cpu-cgroupβœ—
B-h2-paced-100us50,0000.0005129.9β€”server-cpu-cgroupβœ—
B-h2-paced-100us100,0000.0013406.2β€”server-cpu-cgroupβœ—
B-h2-paced-100us250,0000.0005006.5β€”server-cpu-cgroupβœ—

parser path β€” source citations

  • Spring Boot HTTP/2 support β€” ? β†’ source

what this means

this server detects abnormally small DATA frames on h2c and aborts the request with GOAWAY error code 11 (ENHANCE_YOUR_CALM) before consuming the target body. this is in-protocol and effective, but it is not a spec requirement and is specific to http/2.

what to do today

  • if this is an h2 origin, prefer a frontend that terminates h2 into h1 with proxy_request_buffering on upstream.
  • consider imposing a per-stream DATA-frame credit (count, not bytes) before forwarding the body to the application handler.
  • HTTP/2 byte-level flow control (WINDOW_UPDATE) does not bound the number of frames; configure stream-frame-rate limits where the implementation exposes them.

reproducer

the full reproducer for this server is in the paper repo. the docker container pins Spring Boot + Tomcat (h2c) spring-boot-3.3.5 / tomcat-10.1 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