http: allow ignoring unknown upgrade requests#37150
http: allow ignoring unknown upgrade requests#37150ggreenway wants to merge 6 commits intoenvoyproxy:mainfrom
Conversation
Fixes envoyproxy#36305 Signed-off-by: Greg Greenway <ggreenway@apple.com>
|
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
|
Initial questions:
|
|
cc @RyanTheOptimist for spec thoughts |
alyssawilk
left a comment
There was a problem hiding this comment.
I'm fine with this conceptually but as commented would like @RyanTheOptimist (or @DavidSchinazi but he's less likely to respond) thoughts from a spec perspective
and tests, obviously but it's still a draft so can wait for those =P
api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto
Outdated
Show resolved
Hide resolved
api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto
Outdated
Show resolved
Hide resolved
| createFilterChain(FilterChainManager& manager, bool only_create_if_configured = false, | ||
| const FilterChainOptions& options = EmptyFilterChainOptions{}) const PURE; | ||
|
|
||
| enum class UpgradeAction { |
There was a problem hiding this comment.
I think move the comments below up here in case the enum gets used multiple places
|
Yes, Upgrade is HTTP/1 only. However Extended CONNECT provides similar capabilities for H2 and H3. Do we have a similar configuration method for this? |
| // :ref:`upgrade documentation <arch_overview_upgrades>`. | ||
| google.protobuf.BoolValue enabled = 3; | ||
|
|
||
| // If enabled, Envoy will ignore upgrade requests of this type. It is invalid to set both this option and |
There was a problem hiding this comment.
It would be nice if you could explicitly describe what this means.
Ignore could mean pass through or the header could be discarded. Also, there are two headers involved, connection and upgrade. The user should understand the implication for both of them, without reading the source code.
Signed-off-by: Greg Greenway <ggreenway@apple.com>
|
As mentioned by @chlunde above, we also need to remove the parts of the |
|
There's an important distinction between HTTP versions here:
(As a quick side note, RFC 7230 has been obsoleted by RFC 9110 and RFC 9112, please do not refer to it as some parts of it are incorrect). They behave differently: in particular, in HTTP/1.1 the server can "ignore" the Upgrade and still send a successful HTTP/1.1 response without upgrading to a different protocol. In HTTP/2 and 3 however, that is not possible. If the server does not wish to use the other protocol, it has no choice but to reject the request. This gets particularly tricky because Envoy normalizes every Extended CONNECT internally to look like Upgrade. So the information of whether ignoring is allowed or not gets somewhat hard to track down inside Envoy. I worry that this will cause protocol confusion or request smuggling attacks, unless there are strong safeguards in place to ensure that this cannot happen in HTTP/2 or HTTP/3. |
Signed-off-by: Greg Greenway <ggreenway@apple.com>
|
@DavidSchinazi thanks for the clarification on this. I added a check, and renamed the config fields, to document and ensure that ignoring upgrades only happens on http 1.1. |
|
Thanks @ggreenway ! As far as I can tell, this looks safe from a spec perspective. But I'll let folks more familiar with Envoy internals do the detailed code review. |
Signed-off-by: Greg Greenway <ggreenway@apple.com>
|
@ggreenway 👋 , hi, what is going to be the expected behavior after this fix for the HTTP2 upstreams? Is it going to be safe to use HTTP2 clusters when clients supply -H "Connection: Upgrade" -H "Upgrade: TLS/1.3" headers for example? Just want to double check expectations after reading (https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-upgradeconfig) that upgrade config does not work with HTTP2 |
|
@ipoval when Envoy ignores a downstream http/1.1 upgrade request, it will remove the upgrade headers from the request, so the request should be fine for any upstream http version because it no longer requests an upgrade. |
Signed-off-by: Greg Greenway <ggreenway@apple.com>
|
Integration tests reveal that this doesn't work. The http1 codec handles request processing differently if it thinks an upgrade is happening; see |
|
A fix for this would probably have to be in the http1 codec_impl, but that doesn't have access to the configured upgrades which are processed later, so it would probably need to be a change that specifically ignores TLS upgrades. |
Fixes #36305
Add configuration to ignore either all unknown upgrade requests, or specific upgrade requests. This is allowed in https://datatracker.ietf.org/doc/html/rfc7230#section-6.7:
A server MAY ignore a received Upgrade
header field if it wishes to continue using the current protocol on
that connection.
Risk Level: Medium
Testing: TODO
Docs Changes:
Release Notes: TODO