-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HCM: protect against removal of critical response headers by a filter chain. #16745
HCM: protect against removal of critical response headers by a filter chain. #16745
Conversation
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think my vote for making encodeHeaders (although larger change) return a status is that we won't need to check elsewhere in case some other extension point besides filters break status (i think that was the comment on my request side PR). but maybe that should change when that will be a problem
Signed-off-by: Takeshi Yoneda <[email protected]>
Thanks, that makes sense.. but yeah we could expand this check when actually we see other extension points break the status header. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code otherwise looks good to me, deferring to a senior maintainer for any opinions on the approach
@envoyproxy/senior-maintainers
docs/root/configuration/http/http_conn_man/response_code_details.rst
Outdated
Show resolved
Hide resolved
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for fixing this.
LGTM modulo comment request.
Non-blocking comments, fixing this crash is good, but if we want to allow semi-trusted wasm, I think we should do the full suite of header checks that we do in the codec after wasm runs, ensure all headers only have valid characters, we don't allow smuggling by having transfer encoding and content length, relative urls don't start with ../ etc? Is there a plan and/or tracking issue for that?
* Required request headers include :method header, :path for non-CONNECT requests, and | ||
* host/authority for HTTP/1.1 or CONNECT requests. | ||
* @return Status containing the result. If failed, message includes details on which header was | ||
* missing. | ||
*/ | ||
static Http::Status checkRequiredHeaders(const Http::RequestHeaderMap& headers); | ||
static Http::Status checkRequiredRequestHeaders(const Http::RequestHeaderMap& headers); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hear your point about calling this from the codec being really messy.
optional!: Could we at least as part of this PR make the codecs not throw/crash if they get bad data a well? I think we'd prefer to serialize 0 if status code is not present to crashing though Matt may disagree =P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to do so, we should eliminate all the usage of getResponseStatus
and use getResponseStatusNoThrow
instead? e.g.
envoy/source/common/http/http2/codec_impl.cc
Line 336 in 5c51bf1
const uint64_t status = Http::Utility::getResponseStatus(*headers); envoy/source/common/http/http1/codec_impl.cc
Lines 373 to 375 in 5c51bf1
// The contract is that client codecs must ensure that :status is present. ASSERT(headers.Status() != nullptr); uint64_t numeric_status = Utility::getResponseStatus(headers);
I think fixing this is worth a separate PR and discussion, so can I open an issue for now and discuss there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, and as it's optional don't feel obliged to tackle it (though it would be nice!)
I think it's largely a part of removing exceptions from the data plane, which I think @chaoqin-li1123 is looking at
Signed-off-by: Takeshi Yoneda <[email protected]>
yeah that's true and this is somewhat related to the comment by @PiotrSikora #15487 (comment), and yes, we should do Wasm specific check in addition to this Envoy-wide protection. I will open an issue for tracking this. Thanks! |
… chain. (envoyproxy#16745) This is the rework of the previous PR (envoyproxy#15658). Additional Description: Previously, Envoy hasn't been guarded from the removal of critical response headers like :status. This happens when there's misbehaving filter chan, and especially this protection is important when users run their own extensions through Wasm. Resolves envoyproxy#13756 and ref: envoyproxy#15487. Testing: new integration tests Risk: low Signed-off-by: Takeshi Yoneda <[email protected]>
This is the rework of the previous PR (#15658).
Commit Message: HCM: protect against removal of critical response headers by a filter chain.
Additional Description: Previously, Envoy hasn't been guarded from the removal of critical response headers like :status. This happens when there's misbehaving filter chan, and especially this protection is important when users run their own extensions through Wasm. Resolves #13756 and ref: #15487.
Notes
For the request path, Envoy is already guarded by HeaderUtility::checkRequiredHeaders and its error is gracefully handled in the onPoolReady.
The following is the current crash path with uncaught exception caused by removed :status header after filter chains:
envoy/source/common/http/conn_manager_impl.cc
Line 1481 in 5c51bf1
envoy/source/common/http/conn_manager_impl.cc
Line 777 in 5c51bf1
envoy/source/common/http/utility.cc
Line 455 in 5c51bf1
Signed-off-by: Takeshi Yoneda [email protected]