Summary
http4s-blaze-server aggregates the fragments of an incoming WebSocket
message with no limit on total size or fragment count. A client that
completes a WebSocket handshake can send an unterminated fragmented
message and drive unbounded heap growth in the server JVM, resulting in
denial of service via OutOfMemoryError.
Impact
Any http4s application serving WebSocket routes over
BlazeServerBuilder is affected; no non-default configuration is required,
and maxWebSocketBufferSize does not bound the aggregate (it bounds only
individual frames). A single connection sending continuation frames that
never set FIN forces the server to buffer every fragment until the heap is
exhausted, terminating the JVM with OutOfMemoryError on the blaze
selector thread. Small fragments amplify the cost through per-frame object
overhead, so a modest volume of wire bytes is sufficient. Where the
WebSocket endpoint is reachable without authentication the attacker is
unauthenticated and remote; where the handshake requires a principal, any
authenticated client can still trigger it.
Workarounds
- No blaze-server configuration bounds the aggregate;
maxWebSocketBufferSize
is not a mitigation.
- Terminate/limit WebSocket traffic at a fronting layer that enforces
message-size and fragment limits, or disable WebSocket routes.
- Longer term: blaze is EOL upstream; plan migration to a maintained
backend (e.g. ember).
References
Summary
http4s-blaze-serveraggregates the fragments of an incoming WebSocketmessage with no limit on total size or fragment count. A client that
completes a WebSocket handshake can send an unterminated fragmented
message and drive unbounded heap growth in the server JVM, resulting in
denial of service via
OutOfMemoryError.Impact
Any http4s application serving WebSocket routes over
BlazeServerBuilderis affected; no non-default configuration is required,and
maxWebSocketBufferSizedoes not bound the aggregate (it bounds onlyindividual frames). A single connection sending continuation frames that
never set FIN forces the server to buffer every fragment until the heap is
exhausted, terminating the JVM with
OutOfMemoryErroron the blazeselector thread. Small fragments amplify the cost through per-frame object
overhead, so a modest volume of wire bytes is sufficient. Where the
WebSocket endpoint is reachable without authentication the attacker is
unauthenticated and remote; where the handshake requires a principal, any
authenticated client can still trigger it.
Workarounds
maxWebSocketBufferSizeis not a mitigation.
message-size and fragment limits, or disable WebSocket routes.
backend (e.g. ember).
References