diff --git a/browser/brave_content_browser_client_browsertest.cc b/browser/brave_content_browser_client_browsertest.cc
index f4473f4263b2..512674da1df7 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 db13a74ee084..f95d11173eb3 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 acb6daa32794..e80b92bf32c5 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 000000000000..e90c496f60d0
--- /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 000000000000..77bca94dd3ee
--- /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 000000000000..80c2ed7be20c
--- /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 000000000000..686d7f67964b
--- /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 be2a4631f004..7bff666be211 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 6d3d5d09fcec..b63f0fb5a676 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 000000000000..40f708a6c2dc
--- /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 9b56cc4210a9..20e4604e2210 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 000000000000..44ddb41fe95a
Binary files /dev/null and b/test/data/logo-referrer.png differ
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 000000000000..2af9f597cfb8
--- /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 000000000000..0e7a0275f9d6
--- /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 000000000000..de5f7ba8b1be
--- /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 000000000000..ae89db32c975
--- /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 000000000000..bac4a0b1bfa6
--- /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