Summary
Envoy’s HTTP/2 codec may leak a header map and bookkeeping structures upon receiving RST_STREAM immediately followed by the GOAWAY frames from an upstream server.
Affected Component
HTTP/2 codec
Details
In nghttp2, cleanup of pending requests due to receipt of the GOAWAY frame skips de-allocation of the bookkeeping structure and pending compressed header.
The error return code path is taken if connection is already marked for not sending more requests due to GOAWAY frame.
The clean-up code is right after the return statement, causing memory leak.
PoC
- From H/2 server accept the connection from Envoy.
- Send
MAX CONCURRENT STREAMS = 1
- After receiving request
- Send
RST_STREAM for the request
- Send
GO_AWAY with max stream is = 0.
Envoy needs a steady stream of requests from a client.
Upon receiving RST_STREAM Envoy frees up stream capacity on a connection and submits headers for the next request.
In the same I/O operation it also processes GOAWAY and marks connection to not send any more requests.
When processing outbound request queue nghttp2 enters the error handling branch due to connection marked for not sending more requests. In this branch there is no clean-up for the outbound request.
Impact
Denial of service through memory exhaustion.
Attack vector(s)
Specifically crafter response from an untrusted upstream service.
Mitigation
None, apart from disabling HTTP/2 protocol for upstream services.
Detection
Process termination due to out of memory conditions. If collection of memory profile is allowed, the profile will show memory consumed from the submit_headers_shared function in the nghttp2_submit.c file.
Credits
Yan Avlasov yavlasov@google.com
Summary
Envoy’s HTTP/2 codec may leak a header map and bookkeeping structures upon receiving
RST_STREAMimmediately followed by theGOAWAYframes from an upstream server.Affected Component
HTTP/2 codec
Details
In nghttp2, cleanup of pending requests due to receipt of the
GOAWAYframe skips de-allocation of the bookkeeping structure and pending compressed header.The error return code path is taken if connection is already marked for not sending more requests due to
GOAWAYframe.The clean-up code is right after the return statement, causing memory leak.
PoC
MAX CONCURRENT STREAMS= 1RST_STREAMfor the requestGO_AWAYwith max stream is = 0.Envoy needs a steady stream of requests from a client.
Upon receiving
RST_STREAMEnvoy frees up stream capacity on a connection and submits headers for the next request.In the same I/O operation it also processes
GOAWAYand marks connection to not send any more requests.When processing outbound request queue nghttp2 enters the error handling branch due to connection marked for not sending more requests. In this branch there is no clean-up for the outbound request.
Impact
Denial of service through memory exhaustion.
Attack vector(s)
Specifically crafter response from an untrusted upstream service.
Mitigation
None, apart from disabling HTTP/2 protocol for upstream services.
Detection
Process termination due to out of memory conditions. If collection of memory profile is allowed, the profile will show memory consumed from the
submit_headers_sharedfunction in thenghttp2_submit.cfile.Credits
Yan Avlasov yavlasov@google.com