diff --git a/content/browser/renderer_host/local_network_access_util.cc b/content/browser/renderer_host/local_network_access_util.cc index 309bc1dde3db722648cd00437a60095c7016be28..df3986266850fe9273025b1bd89fe27343602b03 100644 --- a/content/browser/renderer_host/local_network_access_util.cc +++ b/content/browser/renderer_host/local_network_access_util.cc @@ -220,9 +220,18 @@ AddressSpace CalculateIPAddressSpace( absl::optional params = absl::nullopt; if (response_head) { - params.emplace(response_head->url_list_via_service_worker, - response_head->parsed_headers, - response_head->remote_endpoint); + std::optional client_address_space; + if (response_head->was_fetched_via_service_worker && + response_head->client_address_space != + network::mojom::IPAddressSpace::kUnknown) { + client_address_space = response_head->client_address_space; + } + params.emplace({ + .client_address_space_inherited_from_service_worker = + client_address_space, + .parsed_headers = &response_head->parsed_headers, + .remote_endpoint = &response_head->remote_endpoint, + }); } AddressSpace computed_ip_address_space = network::CalculateClientAddressSpace(url, params); diff --git a/content/browser/service_worker/service_worker_main_resource_loader.cc b/content/browser/service_worker/service_worker_main_resource_loader.cc index 277af172153285cfde0dea76137ee2a19aa5a4f0..3edc6c9eab61f56ac3cbeef18ad31052518e0423 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader.cc @@ -533,6 +533,10 @@ void ServiceWorkerMainResourceLoader::StartResponse( DCHECK(version->GetMainScriptResponse()); response_head_->ssl_info = version->GetMainScriptResponse()->ssl_info; + CHECK(version->policy_container_host()); + response_head_->client_address_space = + version->policy_container_host()->ip_address_space(); + // Handle a redirect response. ComputeRedirectInfo returns non-null redirect // info if the given response is a redirect. absl::optional redirect_info = diff --git a/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc b/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc index 66226dce5bdc7a5a2003ba07e9c9d50cf6474329..369f9df8b1ad14805a84a78f7bdbbc1e6888c24e 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc @@ -448,6 +448,10 @@ class ServiceWorkerMainResourceLoaderTest : public testing::Test { version_->set_fetch_handler_type( ServiceWorkerVersion::FetchHandlerType::kNotSkippable); version_->SetStatus(ServiceWorkerVersion::ACTIVATED); + PolicyContainerPolicies policies; + policies.ip_address_space = network::mojom::IPAddressSpace::kPrivate; + version_->set_policy_container_host( + base::MakeRefCounted(std::move(policies))); registration_->SetActiveVersion(version_); // Make the registration findable via storage functions. @@ -619,6 +623,9 @@ TEST_F(ServiceWorkerMainResourceLoaderTest, Basic) { EXPECT_FALSE(info->load_timing.receive_headers_end.is_null()); EXPECT_LE(info->load_timing.receive_headers_start, info->load_timing.receive_headers_end); + EXPECT_TRUE(info->was_fetched_via_service_worker); + EXPECT_EQ(info->client_address_space, + network::mojom::IPAddressSpace::kPrivate); ExpectResponseInfo(*info, *CreateResponseInfoFromServiceWorker()); histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent, diff --git a/services/network/public/cpp/ip_address_space_util.cc b/services/network/public/cpp/ip_address_space_util.cc index 774767034ba7191adbcdfde0b391d5e9084907d5..c500365f4ec6299acd2357a9bb10c476cf1768a6 100644 --- a/services/network/public/cpp/ip_address_space_util.cc +++ b/services/network/public/cpp/ip_address_space_util.cc @@ -319,40 +319,18 @@ bool IsLessPublicAddressSpace(IPAddressSpace lhs, IPAddressSpace rhs) { return CollapseUnknown(lhs) < CollapseUnknown(rhs); } -namespace { - -// Helper for CalculateClientAddressSpace() with the same arguments. -// -// If the response was fetched via service workers, returns the last URL in the -// list. Otherwise returns `request_url`. -// -// See: https://fetch.spec.whatwg.org/#concept-response-url-list -const GURL& ResponseUrl( - const GURL& request_url, - absl::optional params) { - if (params.has_value() && !params->url_list_via_service_worker.empty()) { - return params.value().url_list_via_service_worker.back(); - } - return request_url; -} - -} // namespace - -CalculateClientAddressSpaceParams::CalculateClientAddressSpaceParams( - const std::vector& url_list_via_service_worker, - const mojom::ParsedHeadersPtr& parsed_headers, - const net::IPEndPoint& remote_endpoint) - : url_list_via_service_worker(url_list_via_service_worker), - parsed_headers(parsed_headers), - remote_endpoint(remote_endpoint) {} - CalculateClientAddressSpaceParams::~CalculateClientAddressSpaceParams() = default; mojom::IPAddressSpace CalculateClientAddressSpace( const GURL& url, absl::optional params) { - if (ResponseUrl(url, params).SchemeIsFile()) { + if (params.has_value() && + params->client_address_space_inherited_from_service_worker.has_value()) { + return *params->client_address_space_inherited_from_service_worker; + } + + if (url.SchemeIsFile()) { // See: https://wicg.github.io/cors-rfc1918/#file-url. return mojom::IPAddressSpace::kLoopback; } @@ -366,12 +344,12 @@ mojom::IPAddressSpace CalculateClientAddressSpace( DCHECK(params->parsed_headers) << "CalculateIPAddressSpace() called for URL " << url << " with null parsed_headers."; if (ShouldTreatAsPublicAddress( - params->parsed_headers->content_security_policy)) { + (*params->parsed_headers)->content_security_policy)) { return mojom::IPAddressSpace::kPublic; } // Otherwise, calculate the address space via the provided IP address. - return IPEndPointToIPAddressSpace(params->remote_endpoint); + return IPEndPointToIPAddressSpace(*params->remote_endpoint); } mojom::IPAddressSpace CalculateResourceAddressSpace( diff --git a/services/network/public/cpp/ip_address_space_util.h b/services/network/public/cpp/ip_address_space_util.h index 714764ecef4b6d1bb988143093c39e0e92aba589..79817c58509d323fb232020be9cda443489ac9a8 100644 --- a/services/network/public/cpp/ip_address_space_util.h +++ b/services/network/public/cpp/ip_address_space_util.h @@ -8,6 +8,8 @@ #include #include "base/component_export.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/stack_allocated.h" #include "base/strings/string_piece_forward.h" #include "services/network/public/mojom/ip_address_space.mojom-forward.h" #include "services/network/public/mojom/parsed_headers.mojom-forward.h" @@ -80,15 +82,15 @@ bool COMPONENT_EXPORT(NETWORK_CPP) // them nor make copy of them. Parameters must outlive this struct. For example, // passing net::IPEndPoint() as `remote_endpoint` is invalid. struct COMPONENT_EXPORT(NETWORK_CPP) CalculateClientAddressSpaceParams { - CalculateClientAddressSpaceParams( - const std::vector& url_list_via_service_worker, - const mojom::ParsedHeadersPtr& parsed_headers, - const net::IPEndPoint& remote_endpoint); + STACK_ALLOCATED(); + + public: ~CalculateClientAddressSpaceParams(); - const std::vector& url_list_via_service_worker; - const mojom::ParsedHeadersPtr& parsed_headers; - const net::IPEndPoint& remote_endpoint; + const std::optional + client_address_space_inherited_from_service_worker; + const raw_ptr parsed_headers; + const raw_ptr remote_endpoint; }; // Given a request URL and `params`, this function calculates the diff --git a/services/network/public/cpp/ip_address_space_util_unittest.cc b/services/network/public/cpp/ip_address_space_util_unittest.cc index fc989479d52ba4ca2464601933cc6b7f25313adc..f3766e85840545d5365d9d61f974c867592abd34 100644 --- a/services/network/public/cpp/ip_address_space_util_unittest.cc +++ b/services/network/public/cpp/ip_address_space_util_unittest.cc @@ -484,41 +484,28 @@ TEST(IPAddressSpaceUtilTest, CalculateClientAddressSpaceFileURL) { } TEST(IPAddressSpaceUtilTest, - CalculateClientAddressSpaceFetchedViaServiceWorkerFromFile) { - std::vector url_list_via_service_worker = {GURL("http://bar.test"), - GURL("file:///foo")}; + CalculateClientAddressSpaceInheritedFromServiceWorker) { auto parsed_headers = ParsedHeaders::New(); - auto remote_endpoint = net::IPEndPoint(); - CalculateClientAddressSpaceParams params(url_list_via_service_worker, - parsed_headers, remote_endpoint); - - EXPECT_EQ(IPAddressSpace::kLoopback, - CalculateClientAddressSpace(GURL("http://foo.test"), params)); -} - -TEST(IPAddressSpaceUtilTest, - CalculateClientAddressSpaceFetchedViaServiceWorkerFromHttp) { - std::vector url_list_via_service_worker = {GURL("file:///foo"), - GURL("http://bar.test")}; - auto parsed_headers = ParsedHeaders::New(); - auto remote_endpoint = net::IPEndPoint(); - CalculateClientAddressSpaceParams params(url_list_via_service_worker, - parsed_headers, remote_endpoint); - - EXPECT_EQ(IPAddressSpace::kUnknown, - CalculateClientAddressSpace(GURL("http://foo.test"), params)); -} - -TEST(IPAddressSpaceUtilTest, - CalculateClientAddressSpaceFetchedViaServiceWorkerFromHttpInsteadOfFile) { - std::vector url_list_via_service_worker = {GURL("http://bar.test")}; - auto parsed_headers = ParsedHeaders::New(); - auto remote_endpoint = net::IPEndPoint(); - CalculateClientAddressSpaceParams params(url_list_via_service_worker, - parsed_headers, remote_endpoint); - - EXPECT_EQ(IPAddressSpace::kUnknown, - CalculateClientAddressSpace(GURL("file:///foo"), params)); + auto remote_endpoint = IPEndPoint(); + for (const auto ip_address_space : { + mojom::IPAddressSpace::kLookback, + mojom::IPAddressSpace::kLocal, + mojom::IPAddressSpace::kPublic, + }) { + for (const auto& url : { + GURL("file:///foo"), + GURL("http://foo.test"), + }) { + CalculateClientAddressSpaceParams params{ + .client_address_space_inherited_from_service_worker = + ip_address_space, + .parsed_headers = &parsed_headers, + .remote_endpoint = &remote_endpoint, + }; + EXPECT_EQ(ip_address_space, + CalculateClientAddressSpace(GURL(url), params)); + } + } } TEST(IPAddressSpaceUtilTest, CalculateClientAddressSpaceNullParams) { @@ -528,36 +515,42 @@ TEST(IPAddressSpaceUtilTest, CalculateClientAddressSpaceNullParams) { } TEST(IPAddressSpaceUtilTest, CalculateClientAddressSpaceEmptyParams) { - std::vector url_list_via_service_worker = {}; auto parsed_headers = ParsedHeaders::New(); auto remote_endpoint = net::IPEndPoint(); - CalculateClientAddressSpaceParams params(url_list_via_service_worker, - parsed_headers, remote_endpoint); + CalculateClientAddressSpaceParams params{ + .client_address_space_inherited_from_service_worker = std::nullopt, + .parsed_headers = &parsed_headers, + .remote_endpoint = &remote_endpoint, + }; EXPECT_EQ(IPAddressSpace::kUnknown, CalculateClientAddressSpace(GURL("http://foo.test"), params)); } TEST(IPAddressSpaceUtilTest, CalculateClientAddressSpaceIPAddress) { - std::vector url_list_via_service_worker = {}; auto parsed_headers = ParsedHeaders::New(); auto remote_endpoint = IPEndPoint(LocalIPv4Address(), 1234); - CalculateClientAddressSpaceParams params(url_list_via_service_worker, - parsed_headers, remote_endpoint); + CalculateClientAddressSpaceParams params{ + .client_address_space_inherited_from_service_worker = std::nullopt, + .parsed_headers = &parsed_headers, + .remote_endpoint = &remote_endpoint, + }; EXPECT_EQ(IPAddressSpace::kLocal, CalculateClientAddressSpace(GURL("http://foo.test"), params)); } TEST(IPAddressSpaceUtilTest, CalculateClientAddressSpaceTreatAsPublicAddress) { - std::vector url_list_via_service_worker = {}; auto csp = ContentSecurityPolicy::New(); csp->treat_as_public_address = true; auto parsed_headers = ParsedHeaders::New(); parsed_headers->content_security_policy.push_back(std::move(csp)); auto remote_endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 1234); - CalculateClientAddressSpaceParams params(url_list_via_service_worker, - parsed_headers, remote_endpoint); + CalculateClientAddressSpaceParams params{ + .client_address_space_inherited_from_service_worker = std::nullopt, + .parsed_headers = &parsed_headers, + .remote_endpoint = &remote_endpoint, + }; EXPECT_EQ(IPAddressSpace::kPublic, CalculateClientAddressSpace(GURL("http://foo.test"), params)); @@ -568,12 +561,14 @@ TEST(IPAddressSpaceTest, CalculateClientAddressSpaceOverride) { command_line.AppendSwitchASCII(network::switches::kIpAddressSpaceOverrides, "10.2.3.4:80=public,8.8.8.8:8888=local"); - std::vector url_list_via_service_worker = {}; auto parsed_headers = ParsedHeaders::New(); auto remote_endpoint = IPEndPoint(IPAddress(10, 2, 3, 4), 80); - CalculateClientAddressSpaceParams params(url_list_via_service_worker, - parsed_headers, remote_endpoint); + CalculateClientAddressSpaceParams params{ + .client_address_space_inherited_from_service_worker = std::nullopt, + .parsed_headers = &parsed_headers, + .remote_endpoint = &remote_endpoint, + }; EXPECT_EQ(IPAddressSpace::kPublic, CalculateClientAddressSpace(GURL("http://foo.test"), params)); diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 61e5014a219b2077691d826159dbb473aeee62bc..20bb9a2323ca784f7c07a9edd661bd9b86188606 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc @@ -2207,13 +2207,15 @@ void URLLoader::NotifyEarlyResponse( // Calculate IP address space. mojom::ParsedHeadersPtr parsed_headers = PopulateParsedHeaders(headers.get(), url_request_->url()); - std::vector url_list_via_service_worker; net::IPEndPoint transaction_endpoint; bool has_endpoint = url_request_->GetTransactionRemoteEndpoint(&transaction_endpoint); DCHECK(has_endpoint); - CalculateClientAddressSpaceParams params( - url_list_via_service_worker, parsed_headers, transaction_endpoint); + CalculateClientAddressSpaceParams params{ + .client_address_space_inherited_from_service_worker = std::nullopt, + .parsed_headers = &parsed_headers, + .remote_endpoint = &transaction_endpoint, + }; mojom::IPAddressSpace ip_address_space = CalculateClientAddressSpace(url_request_->url(), params);