Commit 6d02b47a authored by Robert Ogden's avatar Robert Ogden Committed by Commit Bot

Harden User-Agent code for Prefetch Proxy's prefetches

Mostly adds testing to ensure the UA header is set correctly, and uses
the content API for the UA string instead.

Change-Id: Id54ec973dc6837b92aa19cde3149e1097423374d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521351
Commit-Queue: Robert Ogden <robertogden@chromium.org>
Commit-Queue: Ryan Sturm <ryansturm@chromium.org>
Auto-Submit: Robert Ogden <robertogden@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824555}
parent 1677b67f
......@@ -70,6 +70,7 @@
#include "components/security_interstitials/content/ssl_cert_reporter.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/variations/variations_params_manager.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
......@@ -78,8 +79,10 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/network_service_util.h"
#include "content/public/common/page_type.h"
#include "content/public/common/user_agent.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_base.h"
#include "content/public/test/browser_test_utils.h"
......@@ -681,6 +684,28 @@ class PrefetchProxyBrowserTest
});
}
// Uses the url's path to match requests since the host from
// EmbeddedTestServer is always 127.0.0.1.
void VerifyOriginRequestsAreIsolated(const std::set<std::string>& paths) {
size_t verified_url_count = 0;
for (const auto& request : origin_server_requests()) {
const GURL& url = request.GetURL();
if (paths.find(url.path()) == paths.end()) {
continue;
}
SCOPED_TRACE(request.GetURL().spec());
EXPECT_EQ(request.headers.find("user-agent")->second,
content::GetFrozenUserAgent(
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseMobileUserAgent),
version_info::GetMajorVersionNumber()));
EXPECT_EQ(request.headers.find("purpose")->second, "prefetch");
verified_url_count++;
}
EXPECT_EQ(paths.size(), verified_url_count);
}
size_t OriginServerRequestCount() const {
base::RunLoop().RunUntilIdle();
return origin_server_request_count_;
......@@ -715,6 +740,8 @@ class PrefetchProxyBrowserTest
if (request.GetURL().spec().find("favicon") != std::string::npos)
return nullptr;
SCOPED_TRACE(request.GetURL().spec());
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
......@@ -1169,6 +1196,8 @@ IN_PROC_BROWSER_TEST_F(PrefetchProxyBrowserTest,
EXPECT_EQ(base::UTF8ToUTF16("Title Of Awesomeness"),
GetWebContents()->GetTitle());
VerifyOriginRequestsAreIsolated({prefetch_url.path()});
// The origin server should not have served this request.
EXPECT_EQ(starting_origin_request_count, OriginServerRequestCount());
}
......@@ -1229,6 +1258,12 @@ IN_PROC_BROWSER_TEST_F(PrefetchProxyBrowserTest,
ui_test_utils::NavigateToURL(browser(), eligible_link_2);
base::RunLoop().RunUntilIdle();
VerifyOriginRequestsAreIsolated({
eligible_link_1.path(),
eligible_link_2.path(),
eligible_link_3.path(),
});
using UkmEntry = ukm::TestUkmRecorder::HumanReadableUkmEntry;
auto expected_entries = std::vector<UkmEntry>{
// eligible_link_1
......@@ -2621,6 +2656,11 @@ IN_PROC_BROWSER_TEST_F(PrefetchProxyWithNSPBrowserTest,
EXPECT_FALSE(found_nsp_mainframe);
EXPECT_FALSE(found_image);
VerifyOriginRequestsAreIsolated({
"/prefetch/prefetch_proxy/prefetch.js",
eligible_link.path(),
});
// Verify the resource load was reported to the subresource manager.
PrefetchProxyService* service =
PrefetchProxyServiceFactory::GetForProfile(browser()->profile());
......
......@@ -8,6 +8,7 @@
#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_functions.h"
......@@ -35,6 +36,7 @@
#include "components/prefs/pref_service.h"
#include "components/prerender/browser/prerender_manager.h"
#include "components/search_engines/template_url_service.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/network_service_instance.h"
......@@ -44,6 +46,8 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/user_agent.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/base/isolation_info.h"
#include "net/base/load_flags.h"
......@@ -700,6 +704,9 @@ void PrefetchProxyTabHelper::StartSinglePrefetch() {
request->load_flags = net::LOAD_DISABLE_CACHE | net::LOAD_PREFETCH;
request->credentials_mode = network::mojom::CredentialsMode::kInclude;
request->headers.SetHeader(content::kCorsExemptPurposeHeaderName, "prefetch");
// Remove the user agent header if it was set so that the network context's
// default is used.
request->headers.RemoveHeader("User-Agent");
request->trusted_params = trusted_params;
request->site_for_cookies = trusted_params.isolation_info.site_for_cookies();
......@@ -1373,7 +1380,10 @@ void PrefetchProxyTabHelper::CreateIsolatedURLLoaderFactory() {
auto context_params = network::mojom::NetworkContextParams::New();
context_params->context_name = "PrefetchProxy";
context_params->user_agent = ::GetUserAgent();
context_params->user_agent = content::GetFrozenUserAgent(
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseMobileUserAgent),
version_info::GetMajorVersionNumber());
context_params->accept_language = net::HttpUtil::GenerateAcceptLanguageHeader(
profile_->GetPrefs()->GetString(language::prefs::kAcceptLanguages));
context_params->initial_custom_proxy_config =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment