From a035f375b9bc26b1497d172205561e9d74e64f48 Mon Sep 17 00:00:00 2001 From: brave-builds Date: Fri, 19 Nov 2021 23:06:00 +0000 Subject: [PATCH] Uplift of #10760 (squashed) to beta --- ...rave_content_browser_client_browsertest.cc | 12 ++ ...cks_network_delegate_helper_browsertest.cc | 189 +++++++++++++++++- ..._hacks_network_delegate_helper_unittest.cc | 18 ++ .../net/url_request/url_request_job.cc | 26 +++ .../net/url_request/url_request_job.h | 19 ++ chromium_src/services/network/cors/DEPS | 3 + .../services/network/cors/cors_url_loader.cc | 18 ++ .../tor/onion_location_navigation_throttle.cc | 7 +- .../tor/onion_location_navigation_throttle.h | 5 + ...ices-network-cors-cors_url_loader.cc.patch | 12 ++ test/BUILD.gn | 1 + test/data/logo-referrer.png | Bin 0 -> 4498 bytes test/data/logo-referrer.png.mock-http-headers | 4 + test/data/post-to-site.html | 19 ++ test/data/referrer_images.html | 39 ++++ test/data/reflect-referrer.html | 9 + .../reflect-referrer.html.mock-http-headers | 3 + 17 files changed, 380 insertions(+), 4 deletions(-) create mode 100644 chromium_src/net/url_request/url_request_job.cc create mode 100644 chromium_src/net/url_request/url_request_job.h create mode 100644 chromium_src/services/network/cors/DEPS create mode 100644 chromium_src/services/network/cors/cors_url_loader.cc create mode 100644 patches/services-network-cors-cors_url_loader.cc.patch create mode 100644 test/data/logo-referrer.png create mode 100644 test/data/logo-referrer.png.mock-http-headers create mode 100644 test/data/post-to-site.html create mode 100644 test/data/referrer_images.html create mode 100644 test/data/reflect-referrer.html create mode 100644 test/data/reflect-referrer.html.mock-http-headers diff --git a/browser/brave_content_browser_client_browsertest.cc b/browser/brave_content_browser_client_browsertest.cc index f4473f4263b27..512674da1df7d 100644 --- a/browser/brave_content_browser_client_browsertest.cc +++ b/browser/brave_content_browser_client_browsertest.cc @@ -535,6 +535,18 @@ IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientReferrerTest, &referrer); EXPECT_EQ(referrer->url, kExtensionUrl); + // Special rule for Onion services. + const GURL kOnionUrl("http://lwkjglkejslkgjel.onion/index.html"); + referrer = kReferrer.Clone(); + referrer->url = kOnionUrl; + client()->MaybeHideReferrer(browser()->profile(), kRequestUrl, kOnionUrl, + &referrer); + EXPECT_EQ(referrer->url, GURL()); // .onion -> normal + referrer = kReferrer.Clone(); + client()->MaybeHideReferrer(browser()->profile(), kOnionUrl, kDocumentUrl, + &referrer); + EXPECT_EQ(referrer->url, kDocumentUrl.GetOrigin()); // normal -> .onion + // Allow referrers for certain URL. content_settings()->SetContentSettingCustomScope( ContentSettingsPattern::FromString(kDocumentUrl.GetOrigin().spec() + "*"), diff --git a/browser/net/brave_site_hacks_network_delegate_helper_browsertest.cc b/browser/net/brave_site_hacks_network_delegate_helper_browsertest.cc index db13a74ee0846..f95d11173eb35 100644 --- a/browser/net/brave_site_hacks_network_delegate_helper_browsertest.cc +++ b/browser/net/brave_site_hacks_network_delegate_helper_browsertest.cc @@ -9,6 +9,7 @@ #include "base/strings/stringprintf.h" #include "brave/common/brave_paths.h" #include "brave/components/brave_shields/browser/brave_shields_util.h" +#include "brave/components/tor/onion_location_navigation_throttle.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -38,6 +39,10 @@ class BraveSiteHacksNetworkDelegateBrowserTest : public InProcessBrowserTest { https_server_.AddDefaultHandlers(GetChromeTestDataDir()); content::SetupCrossSiteRedirector(&https_server_); + https_server_.RegisterRequestMonitor(base::BindRepeating( + &BraveSiteHacksNetworkDelegateBrowserTest::HandleRequest, + base::Unretained(this))); + ASSERT_TRUE(https_server_.Start()); simple_landing_url_ = https_server_.GetURL("a.com", "/simple.html"); @@ -49,6 +54,39 @@ class BraveSiteHacksNetworkDelegateBrowserTest : public InProcessBrowserTest { cross_site_url_ = https_server_.GetURL("b.com", "/navigate-to-site.html"); same_site_url_ = https_server_.GetURL("sub.a.com", "/navigate-to-site.html"); + + onion_url_ = https_server_.GetURL("foobar.onion", "/navigate-to-site.html"); + onion_post_url_ = + https_server_.GetURL("foobar.onion", "/post-to-site.html"); + reflect_referrer_cross_origin_url_ = + https_server_.GetURL("a.com", "/reflect-referrer.html"); + reflect_referrer_cross_origin_redirect_url_ = https_server_.GetURL( + "foobar.onion", + "/server-redirect-307?" + reflect_referrer_cross_origin_url_.spec()); + reflect_referrer_same_origin_url_ = + https_server_.GetURL("foobar.onion", "/reflect-referrer.html"); + reflect_referrer_same_origin_redirect_url_ = https_server_.GetURL( + "foobar.onion", + "/server-redirect-307?" + reflect_referrer_same_origin_url_.spec()); + images_url_ = https_server_.GetURL("foobar.onion", "/referrer_images.html"); + } + + void HandleRequest(const net::test_server::HttpRequest& request) { + base::AutoLock auto_lock(last_headers_lock_); + + auto referrer_it = request.headers.find("Referer"); + if (referrer_it == request.headers.end()) { + last_referrer_[request.GetURL()] = ""; + } else { + last_referrer_[request.GetURL()] = referrer_it->second; + } + + auto origin_it = request.headers.find("Origin"); + if (origin_it == request.headers.end()) { + last_origin_[request.GetURL()] = ""; + } else { + last_origin_[request.GetURL()] = origin_it->second; + } } HostContentSettingsMap* content_settings() { @@ -61,8 +99,6 @@ class BraveSiteHacksNetworkDelegateBrowserTest : public InProcessBrowserTest { command_line->AppendSwitch(switches::kIgnoreCertificateErrors); } - const net::EmbeddedTestServer& https_server() { return https_server_; } - GURL url(const GURL& destination_url, const GURL& navigation_url) { std::string encoded_destination; base::Base64UrlEncode(destination_url.spec(), @@ -97,6 +133,45 @@ class BraveSiteHacksNetworkDelegateBrowserTest : public InProcessBrowserTest { } const GURL& same_site_url() { return same_site_url_; } + const GURL& onion_url() { return onion_url_; } + const GURL& onion_post_url() { return onion_post_url_; } + const GURL& reflect_referrer_cross_origin_url() { + return reflect_referrer_cross_origin_url_; + } + const GURL& reflect_referrer_cross_origin_redirect_url() { + return reflect_referrer_cross_origin_redirect_url_; + } + const GURL& reflect_referrer_same_origin_url() { + return reflect_referrer_same_origin_url_; + } + const GURL& reflect_referrer_same_origin_redirect_url() { + return reflect_referrer_same_origin_redirect_url_; + } + + const GURL& images_url() { return images_url_; } + GURL image_url(const std::string& number) { + GURL::Replacements replacements; + replacements.SetPathStr("/logo-referrer.png"); + replacements.SetQueryStr(number); + return images_url().ReplaceComponents(replacements); + } + + const std::string& last_referrer(const GURL& url) { + base::AutoLock auto_lock(last_headers_lock_); + GURL::Replacements replacements; + replacements.SetHostStr("127.0.0.1"); + const GURL internal_url = url.ReplaceComponents(replacements); + return last_referrer_[internal_url]; + } + + const std::string& last_origin(const GURL& url) { + base::AutoLock auto_lock(last_headers_lock_); + GURL::Replacements replacements; + replacements.SetHostStr("127.0.0.1"); + const GURL internal_url = url.ReplaceComponents(replacements); + return last_origin_[internal_url]; + } + content::WebContents* contents() { return browser()->tab_strip_model()->GetActiveWebContents(); } @@ -119,8 +194,19 @@ class BraveSiteHacksNetworkDelegateBrowserTest : public InProcessBrowserTest { GURL redirect_to_same_site_landing_url_; GURL same_site_url_; GURL simple_landing_url_; - base::FilePath test_data_dir_; + GURL onion_url_; + GURL onion_post_url_; + GURL reflect_referrer_cross_origin_url_; + GURL reflect_referrer_cross_origin_redirect_url_; + GURL reflect_referrer_same_origin_url_; + GURL reflect_referrer_same_origin_redirect_url_; + GURL images_url_; + std::map last_referrer_; + std::map last_origin_; + mutable base::Lock last_headers_lock_; + + base::FilePath test_data_dir_; net::test_server::EmbeddedTestServer https_server_; }; @@ -256,3 +342,100 @@ IN_PROC_BROWSER_TEST_F(BraveSiteHacksNetworkDelegateBrowserTest, EXPECT_EQ(contents()->GetLastCommittedURL(), output); } } + +IN_PROC_BROWSER_TEST_F(BraveSiteHacksNetworkDelegateBrowserTest, + OnionReferrers) { + // Don't block the mock .onion requests. + tor::OnionLocationNavigationThrottle::BlockOnionRequestsOutsideTorForTesting( + false); + + // Same-origin navigations + { + const GURL dest_url = reflect_referrer_same_origin_url(); + const GURL same_origin_test_url = url(dest_url, onion_url()); + NavigateToURLAndWaitForRedirects(same_origin_test_url, dest_url); + EXPECT_EQ(last_referrer(dest_url), same_origin_test_url.spec()); + EXPECT_EQ(last_origin(dest_url), ""); + + // Redirect + const GURL intermediate_url = reflect_referrer_same_origin_redirect_url(); + const GURL same_origin_redirect_test_url = + url(intermediate_url, onion_url()); + NavigateToURLAndWaitForRedirects(same_origin_redirect_test_url, dest_url); + EXPECT_EQ(last_referrer(dest_url), same_origin_redirect_test_url.spec()); + EXPECT_EQ(last_origin(dest_url), ""); + } + { + // POST + const GURL dest_url = reflect_referrer_same_origin_url(); + const GURL same_origin_test_url = url(dest_url, onion_post_url()); + NavigateToURLAndWaitForRedirects(same_origin_test_url, dest_url); + EXPECT_EQ(last_referrer(dest_url), same_origin_test_url.spec()); + std::string full_origin = same_origin_test_url.GetOrigin().spec(); + full_origin.pop_back(); // CORS headers don't use canonical forms. + EXPECT_EQ(last_origin(dest_url), full_origin); + + // Redirect + const GURL intermediate_url = reflect_referrer_same_origin_redirect_url(); + const GURL same_origin_redirect_test_url = + url(intermediate_url, onion_post_url()); + NavigateToURLAndWaitForRedirects(same_origin_redirect_test_url, dest_url); + EXPECT_EQ(last_referrer(dest_url), same_origin_redirect_test_url.spec()); + EXPECT_EQ(last_origin(dest_url), full_origin); + } + + // Cross-origin navigations + { + const GURL dest_url = reflect_referrer_cross_origin_url(); + NavigateToURLAndWaitForRedirects(url(dest_url, onion_url()), dest_url); + EXPECT_EQ(last_referrer(dest_url), ""); + EXPECT_EQ(last_origin(dest_url), ""); + + // Redirect + const GURL intermediate_url = reflect_referrer_cross_origin_redirect_url(); + NavigateToURLAndWaitForRedirects(url(intermediate_url, onion_url()), + dest_url); + EXPECT_EQ(last_referrer(dest_url), ""); + EXPECT_EQ(last_origin(dest_url), ""); + } + { + // POST + const GURL dest_url = reflect_referrer_cross_origin_url(); + NavigateToURLAndWaitForRedirects(url(dest_url, onion_post_url()), dest_url); + EXPECT_EQ(last_referrer(dest_url), ""); + EXPECT_EQ(last_origin(dest_url), "null"); + + // Redirect + const GURL intermediate_url = reflect_referrer_cross_origin_redirect_url(); + NavigateToURLAndWaitForRedirects(url(intermediate_url, onion_post_url()), + dest_url); + EXPECT_EQ(last_referrer(dest_url), ""); + EXPECT_EQ(last_origin(dest_url), "null"); + } + + NavigateToURLAndWaitForRedirects(images_url(), images_url()); + + // Same-origin sub-requests + std::string full_origin = images_url().GetOrigin().spec(); + full_origin.pop_back(); // CORS headers don't use canonical forms. + EXPECT_EQ(last_referrer(image_url("1")), images_url().spec()); + EXPECT_EQ(last_origin(image_url("1")), ""); // nocors + EXPECT_EQ(last_referrer(image_url("2")), images_url().spec()); + EXPECT_EQ(last_origin(image_url("2")), full_origin); + // Redirects + EXPECT_EQ(last_referrer(image_url("3")), images_url().spec()); + EXPECT_EQ(last_origin(image_url("3")), ""); // nocors + EXPECT_EQ(last_referrer(image_url("4")), images_url().spec()); + EXPECT_EQ(last_origin(image_url("4")), full_origin); + + // Cross-origin sub-requests + EXPECT_EQ(last_referrer(image_url("5")), ""); + EXPECT_EQ(last_origin(image_url("5")), ""); // nocors + EXPECT_EQ(last_referrer(image_url("6")), ""); + EXPECT_EQ(last_origin(image_url("6")), "null"); + // Redirects + EXPECT_EQ(last_referrer(image_url("7")), ""); + EXPECT_EQ(last_origin(image_url("7")), ""); // nocors + EXPECT_EQ(last_referrer(image_url("8")), ""); + EXPECT_EQ(last_origin(image_url("8")), "null"); +} diff --git a/browser/net/brave_site_hacks_network_delegate_helper_unittest.cc b/browser/net/brave_site_hacks_network_delegate_helper_unittest.cc index 102b709a3a439..a08fef5ef2d2b 100644 --- a/browser/net/brave_site_hacks_network_delegate_helper_unittest.cc +++ b/browser/net/brave_site_hacks_network_delegate_helper_unittest.cc @@ -13,6 +13,7 @@ #include "brave/browser/net/url_context.h" #include "brave/common/network_constants.h" #include "net/base/net_errors.h" +#include "net/url_request/url_request_job.h" #include "testing/gtest/include/gtest/gtest.h" using brave::ResponseCallback; @@ -100,6 +101,23 @@ TEST(BraveSiteHacksNetworkDelegateHelperTest, } } +TEST(BraveSiteHacksNetworkDelegateHelperTest, OnionReferrerStripped) { + const GURL original_referrer( + "https://" + "brave4u7jddbv7cyviptqjc7jusxh72uik7zt6adtckl5f4nwy2v72qd.onion/"); + const GURL destination("https://brave.com"); + + // Cross-origin request from a .onion gets empty referrer. + auto url1 = net::URLRequestJob::ComputeReferrerForPolicy( + net::ReferrerPolicy::NEVER_CLEAR, original_referrer, destination); + EXPECT_EQ(url1, GURL()); + + // Cross-origin request to a .onion gets normal referrer. + auto url2 = net::URLRequestJob::ComputeReferrerForPolicy( + net::ReferrerPolicy::NEVER_CLEAR, destination, original_referrer); + EXPECT_EQ(url2, destination.GetOrigin()); +} + TEST(BraveSiteHacksNetworkDelegateHelperTest, QueryStringUntouched) { const std::vector urls({ "https://example.com/", diff --git a/chromium_src/net/url_request/url_request_job.cc b/chromium_src/net/url_request/url_request_job.cc new file mode 100644 index 0000000000000..e90c496f60d0e --- /dev/null +++ b/chromium_src/net/url_request/url_request_job.cc @@ -0,0 +1,26 @@ +/* Copyright 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "net/url_request/url_request_job.h" + +// Strip referrer for cross-origin requests from a .onion hostname. +// This also affects the Origin header outside of CORS requests. +#define ComputeReferrerForPolicy \ + ComputeReferrerForPolicy( \ + ReferrerPolicy policy, const GURL& original_referrer, \ + const GURL& destination, bool* same_origin_out_for_metrics) { \ + if (base::EndsWith(original_referrer.host_piece(), ".onion", \ + base::CompareCase::INSENSITIVE_ASCII) && \ + !url::IsSameOriginWith(original_referrer, destination)) { \ + return GURL(); \ + } \ + return ComputeReferrerForPolicy_Chromium( \ + policy, original_referrer, destination, same_origin_out_for_metrics); \ + } \ + GURL URLRequestJob::ComputeReferrerForPolicy_Chromium + +#include "../../../../net/url_request/url_request_job.cc" + +#undef ComputeReferrerForPolicy diff --git a/chromium_src/net/url_request/url_request_job.h b/chromium_src/net/url_request/url_request_job.h new file mode 100644 index 0000000000000..77bca94dd3ee6 --- /dev/null +++ b/chromium_src/net/url_request/url_request_job.h @@ -0,0 +1,19 @@ +/* Copyright 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_CHROMIUM_SRC_NET_URL_REQUEST_URL_REQUEST_JOB_H_ +#define BRAVE_CHROMIUM_SRC_NET_URL_REQUEST_URL_REQUEST_JOB_H_ + +#define ComputeReferrerForPolicy \ + ComputeReferrerForPolicy( \ + ReferrerPolicy policy, const GURL& original_referrer, \ + const GURL& destination, bool* same_origin_out_for_metrics = nullptr); \ + static GURL ComputeReferrerForPolicy_Chromium + +#include "../../../../net/url_request/url_request_job.h" + +#undef ComputeReferrerForPolicy + +#endif // BRAVE_CHROMIUM_SRC_NET_URL_REQUEST_URL_REQUEST_JOB_H_ diff --git a/chromium_src/services/network/cors/DEPS b/chromium_src/services/network/cors/DEPS new file mode 100644 index 0000000000000..80c2ed7be20c1 --- /dev/null +++ b/chromium_src/services/network/cors/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+../../../../../services/network/cors", +] diff --git a/chromium_src/services/network/cors/cors_url_loader.cc b/chromium_src/services/network/cors/cors_url_loader.cc new file mode 100644 index 0000000000000..686d7f67964b2 --- /dev/null +++ b/chromium_src/services/network/cors/cors_url_loader.cc @@ -0,0 +1,18 @@ +/* Copyright 2021 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Nullify the Origin header for cross-origin CORS requests +// originating from a .onion address. +#define BRAVE_CORS_URL_LOADER_START_REQUEST \ + if (base::EndsWith(request_.request_initiator->host(), ".onion", \ + base::CompareCase::INSENSITIVE_ASCII) && \ + !request_.request_initiator->IsSameOriginWith( \ + url::Origin::Create(request_.url))) { \ + request_.headers.SetHeader(net::HttpRequestHeaders::kOrigin, \ + url::Origin().Serialize()); \ + } else /* NOLINT */ + +#include "../../../../../services/network/cors/cors_url_loader.cc" +#undef BRAVE_CORS_URL_LOADER_START_REQUEST diff --git a/components/tor/onion_location_navigation_throttle.cc b/components/tor/onion_location_navigation_throttle.cc index be2a4631f004f..7bff666be211c 100644 --- a/components/tor/onion_location_navigation_throttle.cc +++ b/components/tor/onion_location_navigation_throttle.cc @@ -35,6 +35,9 @@ bool GetOnionLocation(const net::HttpResponseHeaders* headers, } // namespace +bool OnionLocationNavigationThrottle:: + block_onion_requests_outside_tor_for_testing_ = true; + // static std::unique_ptr OnionLocationNavigationThrottle::MaybeCreateThrottleFor( @@ -106,7 +109,9 @@ OnionLocationNavigationThrottle::WillStartRequest() { OnionLocationTabHelper::SetOnionLocation( navigation_handle()->GetWebContents(), url); } - return content::NavigationThrottle::BLOCK_REQUEST; + return block_onion_requests_outside_tor_for_testing_ + ? content::NavigationThrottle::BLOCK_REQUEST + : content::NavigationThrottle::PROCEED; } else { OnionLocationTabHelper::SetOnionLocation( navigation_handle()->GetWebContents(), GURL()); diff --git a/components/tor/onion_location_navigation_throttle.h b/components/tor/onion_location_navigation_throttle.h index 6d3d5d09fcecd..b63f0fb5a676b 100644 --- a/components/tor/onion_location_navigation_throttle.h +++ b/components/tor/onion_location_navigation_throttle.h @@ -44,7 +44,12 @@ class OnionLocationNavigationThrottle : public content::NavigationThrottle { ThrottleCheckResult WillStartRequest() override; const char* GetNameForLogging() override; + static void BlockOnionRequestsOutsideTorForTesting(bool block) { + block_onion_requests_outside_tor_for_testing_ = block; + } + private: + static bool block_onion_requests_outside_tor_for_testing_; bool is_tor_profile_ = false; PrefService* pref_service_ = nullptr; diff --git a/patches/services-network-cors-cors_url_loader.cc.patch b/patches/services-network-cors-cors_url_loader.cc.patch new file mode 100644 index 0000000000000..40f708a6c2dc3 --- /dev/null +++ b/patches/services-network-cors-cors_url_loader.cc.patch @@ -0,0 +1,12 @@ +diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc +index dbacb3e96d1f46a6e5eb5080c69a7bb67058e27c..abb62f7cab19343998c3cd9d313348a5b0220bc6 100644 +--- a/services/network/cors/cors_url_loader.cc ++++ b/services/network/cors/cors_url_loader.cc +@@ -528,6 +528,7 @@ void CorsURLLoader::StartRequest() { + (fetch_cors_flag_ || + (request_.method != net::HttpRequestHeaders::kGetMethod && + request_.method != net::HttpRequestHeaders::kHeadMethod))) { ++ BRAVE_CORS_URL_LOADER_START_REQUEST + if (tainted_) { + request_.headers.SetHeader(net::HttpRequestHeaders::kOrigin, + url::Origin().Serialize()); diff --git a/test/BUILD.gn b/test/BUILD.gn index 809d5db7708f4..4c1b923763e16 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -745,6 +745,7 @@ if (!is_android) { "//brave/components/debounce/browser", "//brave/components/debounce/common", "//brave/components/resources:strings_grit", + "//brave/components/tor", "//brave/renderer/test:browser_tests", "//brave/vendor/bat-native-ads", "//brave/vendor/bat-native-ledger", diff --git a/test/data/logo-referrer.png b/test/data/logo-referrer.png new file mode 100644 index 0000000000000000000000000000000000000000..44ddb41fe95ad2a158eea6ba4259338289ba9e18 GIT binary patch literal 4498 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%0DbK`) z-rifn9g7zI;X9NT0frl&yvCnhXgrPVFNyac3QT~|3<4fLN@5Y|J+|+O_lJuH2TZ`wnDFEb(3-1(Awn`^Naz|X zf81-S5LpEW3Z~B7!H^IL5=3Knl6${29t=%3|I{6)-)7=G{w<-b%3q(R1`` zI>*-LD0RiQspjv=gOug+i-6nmTCxD63K#>LRRCduD{Z2~GjPf1&j;Ez;-^!q1ICD_ z^8rHxRqL~KjyTfTD#nrE*dZS(b*G`AqSC|cC8k;6F*jr(Oyzy6BLLG39Li~KU^jyl zmF;I*mSF?|42l8BTeLh(Fu)kafHWFzm1t{nC9Tj+1nsQ z11tchg}0%Gy@ZVc768*6oH)|AUIS_;s)jAKuRH1mFow6Gm7KS*z2HQ1?dBoO^zIEX z1~^mpHW=&-Lyrtg5WDvD4w${7zzSiSYTfbfsKKbW!0d%-bfKE2M>I!p5#nOIUIViS z4)tW1UL&8_uR`-Gg98R0M}=rp`eo=_^9~9afFqXFCw1`K81H( k_uqOB_2ht%^nU>c08H4uWlB>TdH?_b07*qoM6N<$g0Co7Pyhe` literal 0 HcmV?d00001 diff --git a/test/data/logo-referrer.png.mock-http-headers b/test/data/logo-referrer.png.mock-http-headers new file mode 100644 index 0000000000000..2af9f597cfb8f --- /dev/null +++ b/test/data/logo-referrer.png.mock-http-headers @@ -0,0 +1,4 @@ +HTTP/1.1 200 OK +Cache-Control: no-store +Content-Type: image/png +Access-Control-Allow-Origin: * diff --git a/test/data/post-to-site.html b/test/data/post-to-site.html new file mode 100644 index 0000000000000..0e7a0275f9d69 --- /dev/null +++ b/test/data/post-to-site.html @@ -0,0 +1,19 @@ + + + + +

+ +

+

Waiting for JS form submission...

+ + diff --git a/test/data/referrer_images.html b/test/data/referrer_images.html new file mode 100644 index 0000000000000..de5f7ba8b1be2 --- /dev/null +++ b/test/data/referrer_images.html @@ -0,0 +1,39 @@ + + + + + + + + +
+ + + +> + + + diff --git a/test/data/reflect-referrer.html b/test/data/reflect-referrer.html new file mode 100644 index 0000000000000..ae89db32c975b --- /dev/null +++ b/test/data/reflect-referrer.html @@ -0,0 +1,9 @@ + + +

Referrer (JS):

+ + + diff --git a/test/data/reflect-referrer.html.mock-http-headers b/test/data/reflect-referrer.html.mock-http-headers new file mode 100644 index 0000000000000..bac4a0b1bfa66 --- /dev/null +++ b/test/data/reflect-referrer.html.mock-http-headers @@ -0,0 +1,3 @@ +HTTP/1.1 200 OK +Cache-Control: no-store +Content-Type: text/html