http: switching from XFP to scheme#17372
Conversation
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
mattklein123
left a comment
There was a problem hiding this comment.
Thanks for tackling this really tough set of changes. A few high level comments.
- I would appreciate it if you could split out the rename from the other changes, since I think it would make the tricky stuff easier to review?
- In terms of documentation, here is what I would recommend:
- Potential changes to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers.html#scheme
- Maybe a new HTTP FAQ section with a new entry on scheme/XFP handling?
- Maybe a new section here on scheme handling? https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/http (FAQ and arch overview can cross link as you see fit.)
/wait
source/common/http/utility.cc
Outdated
| !headers.getSchemeValue().empty()) { | ||
| return headers.getSchemeValue(); | ||
| } | ||
| return headers.getXForwardedProtoValue(); |
There was a problem hiding this comment.
What are the cases in which scheme is not but XFP is set? I thought we should always set scheme now early on in the request lifecycle if it's not otherwise set? Can you add more comments?
There was a problem hiding this comment.
They're always set at the same point in the HCM so will only be absent with buggy filters.
I can remove the failover here and there and let folks with buggy filters get buggy behavior :-P
source/common/router/config_impl.cc
Outdated
| absl::string_view getXFPOrScheme(const Http::RequestHeaderMap& headers) { | ||
| absl::string_view xfp = headers.getXForwardedProtoValue(); | ||
| return xfp.empty() ? headers.getSchemeValue() : xfp; | ||
| } |
There was a problem hiding this comment.
Not sure if this is worth co-locating with Utility::getScheme for comment clarity? At first glance I thought it was the same vs. the inverse.
source/common/router/config_impl.cc
Outdated
| // TODO(alyssar, mattklein123) is the goal here to force TLS, or force https: | ||
| // scheme? Maybe upstreams will get confused if seeing an http url. |
There was a problem hiding this comment.
The original intent here (from a very long time ago) was definitely to force TLS, not force the scheme. So I think this is probably correct?
There was a problem hiding this comment.
yeah the only weirdness is then if you have an https:// request in cleartext would you then not serve a redirect to https://foo.com and functionally end up in a redirect loop?
source/common/router/config_impl.cc
Outdated
| // No scheme header. This normally only happens when ActiveStream::decodeHeaders | ||
| // bails early (as it rejects a request), so there is no routing is going to happen anyway. |
There was a problem hiding this comment.
OK this answers my question above. Maybe just move those functions to next to each other and put this comment in each one?
source/common/router/router.cc
Outdated
| absl::string_view xfp = headers.getXForwardedProtoValue(); | ||
| if (Http::HeaderUtility::schemeIsValid(xfp)) { | ||
| headers.setScheme(xfp); |
There was a problem hiding this comment.
This is hurting my brain (should have done this earlier in the day). How come this case isn't using the scheme header if we are preserving downstream scheme? More comments?
| "envoy.reloadable_features.vhds_heartbeats", | ||
| "envoy.reloadable_features.wasm_cluster_name_envoy_grpc", | ||
| "envoy.reloadable_features.upstream_http2_flood_checks", | ||
| "envoy.reloadable_features.use_scheme_header", |
There was a problem hiding this comment.
nit: not sure what would be better, but making this a bit more descriptive would be good.
|
Thanks this LGTM. Can you merge main? /wait |
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
|
merged, but alas needs a merge stamp |
Corrects all Envoy uses of ForwardedProto which actually want request URI over to :scheme As a reminder, XFP indicates the encryption of the (original) downstream connection where :scheme is part of the URI and the resource requested. It's legal (though unusual) to request http:// urls over a TLS connection for HTTP/2. It's possible (if ill advised) to have an internal mesh forwarding https schemed requests in the clear. Current uses of X-Forwarded-Proto are in the HCM, clearing XFP from untrusted users (unchanged) in the HCM, setting absent XFP based on downstream transport security (unchanged) in the HCM setting absent :scheme to XFP (unchanged) in buildOriginalUri, changing from using XFP to scheme (changed. new URIs should be based on original URIs not on transport security. in the router, clearing default port based on XFP (unchanged) in the router serving redirect URLs based on scheme (changed - used to be XFP but is now based on the scheme of the original URI) in the router, applying SSL route redirect based on XFP (unchanged) in the router, using :scheme for internal redirect url checks (changed - used to use XFP. new URIs should be based on original URI) in the cache filter, using :scheme to serve content (changed we used to serve based on XFP but if http://foo.com/ differs from https://foo.com and the http version is requested over a TLS connection the http response should be served) in oath2 serving redirect URLs based on scheme (changed this used to be based on SFP but URLs should be based on original URL scheme) Risk Level: High Testing: updated tests Docs Changes: inline Release Notes: inline Runtime guard: envoy.reloadable_features.correct_scheme_and_xfp Fixes envoyproxy#14587 Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Corrects all Envoy uses of ForwardedProto which actually want request URI over to :scheme
As a reminder, XFP indicates the encryption of the (original) downstream connection where :scheme is part of the URI and the resource requested. It's legal (though unusual) to request http:// urls over a TLS connection for HTTP/2. It's possible (if ill advised) to have an internal mesh forwarding https schemed requests in the clear.
Current uses of X-Forwarded-Proto are
Risk Level: High
Testing: updated tests
Docs Changes: inline
Release Notes: inline
Runtime guard: envoy.reloadable_features.correct_scheme_and_xfp
Fixes #14587