Skip to content

HCM: protect against removal of critical response headers by a filter chain.#16745

Merged
alyssawilk merged 8 commits intoenvoyproxy:mainfrom
mathetake:missing-response-headers
Jun 2, 2021
Merged

HCM: protect against removal of critical response headers by a filter chain.#16745
alyssawilk merged 8 commits intoenvoyproxy:mainfrom
mathetake:missing-response-headers

Conversation

@mathetake
Copy link
Copy Markdown
Member

@mathetake mathetake commented Jun 1, 2021

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:

chargeStats(headers);

uint64_t response_code = Utility::getResponseStatus(headers);

throw CodecClientException(":status must be specified and a valid unsigned long");

Signed-off-by: Takeshi Yoneda takeshi@tetrate.io

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
@mathetake mathetake changed the title HCM: protect against removal of critical response headers. HCM: protect against removal of critical response headers by a filter chain. Jun 1, 2021
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
@mathetake mathetake marked this pull request as ready for review June 1, 2021 09:11
mathetake added 2 commits June 1, 2021 18:25
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Copy link
Copy Markdown
Contributor

@asraa asraa left a 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 <takeshi@tetrate.io>
@mathetake mathetake requested a review from asraa June 1, 2021 12:48
@mathetake
Copy link
Copy Markdown
Member Author

we won't need to check elsewhere in case some other extension point besides filters break status

Thanks, that makes sense.. but yeah we could expand this check when actually we see other extension points break the status header.

asraa
asraa previously approved these changes Jun 1, 2021
Copy link
Copy Markdown
Contributor

@asraa asraa left a 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

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Copy link
Copy Markdown
Contributor

@alyssawilk alyssawilk left a 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?

* missing.
*/
static Http::Status checkRequiredHeaders(const Http::RequestHeaderMap& headers);
static Http::Status checkRequiredRequestHeaders(const Http::RequestHeaderMap& headers);
Copy link
Copy Markdown
Contributor

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

Copy link
Copy Markdown
Member Author

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.

I think fixing this is worth a separate PR and discussion, so can I open an issue for now and discuss there?

Copy link
Copy Markdown
Contributor

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 <takeshi@tetrate.io>
@mathetake
Copy link
Copy Markdown
Member Author

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?

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!

@mathetake mathetake requested a review from alyssawilk June 2, 2021 00:43
@alyssawilk alyssawilk merged commit 13f1860 into envoyproxy:main Jun 2, 2021
@mathetake mathetake deleted the missing-response-headers branch June 2, 2021 23:08
leyao-daily pushed a commit to leyao-daily/envoy that referenced this pull request Sep 30, 2021
… 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 <takeshi@tetrate.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gracefully handle removal of critical headers by filters

3 participants