Skip to content

Commit

Permalink
CVE-2021-43824
Browse files Browse the repository at this point in the history
jwt_atuhn: fixed the crash when a CONNECT request is sent to JWT filter
configured with regex match.

Signed-off-by: Yan Avlasov <yavlasov@google.com>
  • Loading branch information
yanavlasov authored and RyanTheOptimist committed Feb 22, 2022
1 parent ce0ae30 commit 9371333
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Bug Fixes
* access_log: fix memory leak when reopening an access log fails. Access logs will now try to be reopened on each subsequent flush attempt after a failure.
* data plane: fixing error handling where writing to a socket failed while under the stack of processing. This should genreally affect HTTP/3. This behavioral change can be reverted by setting ``envoy.reloadable_features.allow_upstream_inline_write`` to false.
* eds: fix the eds cluster update by allowing update on the locality of the cluster endpoints. This behavioral change can be temporarily reverted by setting runtime guard ``envoy.reloadable_features.support_locality_update_on_eds_cluster_endpoints`` to false.
* jwt_authn: fixed the crash when a CONNECT request is sent to JWT filter configured with regex match on the Host header.
* tcp_proxy: fix a crash that occurs when configured for :ref:`upstream tunneling <envoy_v3_api_field_extensions.filters.network.tcp_proxy.v3.TcpProxy.tunneling_config>` and the downstream connection disconnects while the the upstream connection or http/2 stream is still being established.
* tls: fix a bug while matching a certificate SAN with an exact value in ``match_typed_subject_alt_names`` of a listener where wildcard ``*`` character is not the only character of the dns label. Example, ``baz*.example.net`` and ``*baz.example.net`` and ``b*z.example.net`` will match ``baz1.example.net`` and ``foobaz.example.net`` and ``buzz.example.net``, respectively.
* upstream: fix stack overflow when a cluster with large number of idle connections is removed.
Expand Down
3 changes: 3 additions & 0 deletions source/extensions/filters/http/jwt_authn/matcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ class RegexMatcherImpl : public BaseMatcherImpl {

bool matches(const Http::RequestHeaderMap& headers) const override {
if (BaseMatcherImpl::matchRoute(headers)) {
if (headers.Path() == nullptr) {
return false;
}
const Http::HeaderString& path = headers.Path()->value();
const absl::string_view query_string = Http::Utility::findQueryStringStart(path);
absl::string_view path_view = path.getStringView();
Expand Down
27 changes: 27 additions & 0 deletions test/extensions/filters/http/jwt_authn/filter_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,33 @@ TEST_P(LocalJwksIntegrationTest, FilterStateRequirement) {
}
}

// Verify that JWT config with RegEx matcher can handle CONNECT requests.
TEST_P(LocalJwksIntegrationTest, ConnectRequestWithRegExMatch) {
config_helper_.prependFilter(getAuthFilterConfig(ExampleConfigWithRegEx, true));
initialize();

codec_client_ = makeHttpConnection(lookupPort("http"));

auto encoder_decoder = codec_client_->startRequest(Http::TestRequestHeaderMapImpl{
{":method", "CONNECT"},
{":authority", "host.com:80"},
{"authorization", "Bearer " + std::string(GoodToken)},
});
request_encoder_ = &encoder_decoder.first;
auto response = std::move(encoder_decoder.second);

if (downstreamProtocol() == Http::CodecType::HTTP1) {
// Because CONNECT requests for HTTP/1 do not include a path, they will fail
// to find a route match and return a 404.
ASSERT_TRUE(response->waitForEndStream());
ASSERT_TRUE(response->complete());
EXPECT_EQ("404", response->headers().getStatusValue());
} else {
ASSERT_TRUE(response->waitForReset());
ASSERT_TRUE(codec_client_->waitForDisconnect());
}
}

// The test case with a fake upstream for remote Jwks server.
class RemoteJwksIntegrationTest : public HttpProtocolIntegrationTest {
public:
Expand Down
31 changes: 31 additions & 0 deletions test/extensions/filters/http/jwt_authn/test_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,37 @@ const char ExampleConfig[] = R"(
bypass_cors_preflight: true
)";

const char ExampleConfigWithRegEx[] = R"(
providers:
example_provider:
issuer: https://example.com
audiences:
- example_service
- http://example_service1
- https://example_service2/
remote_jwks:
http_uri:
uri: https://pubkey_server/pubkey_path
cluster: pubkey_cluster
timeout:
seconds: 5
cache_duration:
seconds: 600
forward_payload_header: sec-istio-auth-userinfo
rules:
- match:
safe_regex:
google_re2: {}
regex: "/somethig/.*"
requires:
provider_name: "example_provider"
- match:
path: "/"
requires:
provider_name: "example_provider"
bypass_cors_preflight: true
)";

// The name of provider for above config.
const char ProviderName[] = "example_provider";

Expand Down

0 comments on commit 9371333

Please sign in to comment.