Open iosetek opened 1 month ago
I investigated a bit more the root cause.
OnHttpRequestBody
current expected behaviour (in a simplified version) is the following:
types.ActionPause
as far as endOfStream
is set to false, buffering all the body chunks.endOfStream
is set to true
, it means that the whole body has been received. So tx.ProcessRequestBody()
is called, and if no interruption is raised, the stream is let continue via return types.ActionContinue
.The interesting behavior with a request that comes with trailers is that the return types.ActionPause
is not honored, and the stream continues flowing by triggering OnHttpRequestTrailers
.
It can be tested by just setting
func (ctx *httpContext) OnHttpRequestBody(bodySize int, endOfStream bool) types.Action {
return types.ActionPause
}
When a request with body and without trailers is sent, we get a stream timeout
error, but when trailers come into play, the stream just flows.
That being said, the proposed workaround about relying on OnHttpRequestTrailers
as another enforcement point before reaching upstream server
The Coraza Envoy WASM plugin contains a bug that allows bypassing request payload scanning for HTTP 2 requests with trailers
I've described it in the README.md located there https://github.com/iosetek/coraza-proxy-wasm/blob/fix-bypassing-request-body-scanning/demo/trailer_bypass_attack/README.md
The existing implementation triggers request payload scanning when end_of_stream parameter is set to true: https://github.com/corazawaf/coraza-proxy-wasm/blob/d1d6f28e419aead88005c088b01e5d3f04d69b70/wasmplugin/plugin.go#L432
The thing is, that parameter will NOT be set to true for HTTP 2 requests with trailers. This is because end_of_stream is set to true only if no more payload chunks will arrive AND there will be no request trailers.
This scenario may be easily omitted, as it doesn't happen for HTTP 1 - even though HTTP standard allows adding request trailers, the Envoy team has decided to not trigger onRequestTrailers for HTTP 1 as most servers do not support trailers properly for HTTP 1.
To address the issue, I've raised a PR with solution proposal https://github.com/corazawaf/coraza-proxy-wasm/pull/288. It also contains the demo directory which is meant for reviewers to easily investigate the issue and see how the change affects the problem. The demo directory is not intended to be merged in the final stage.