summaryrefslogtreecommitdiff
path: root/chromium/content/browser/net
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/content/browser/net
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/content/browser/net')
-rw-r--r--chromium/content/browser/net/cookie_store_factory.cc4
-rw-r--r--chromium/content/browser/net/cross_origin_opener_policy_reporter.cc190
-rw-r--r--chromium/content/browser/net/cross_origin_opener_policy_reporter.h95
-rw-r--r--chromium/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc159
-rw-r--r--chromium/content/browser/net/network_errors_listing_ui.cc9
5 files changed, 449 insertions, 8 deletions
diff --git a/chromium/content/browser/net/cookie_store_factory.cc b/chromium/content/browser/net/cookie_store_factory.cc
index 1f23008c71b..c4743b67066 100644
--- a/chromium/content/browser/net/cookie_store_factory.cc
+++ b/chromium/content/browser/net/cookie_store_factory.cc
@@ -10,7 +10,6 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
-#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
@@ -57,8 +56,7 @@ std::unique_ptr<net::CookieStore> CreateCookieStore(
config.background_task_runner;
if (!client_task_runner.get()) {
- client_task_runner =
- base::CreateSingleThreadTaskRunner({BrowserThread::IO});
+ client_task_runner = GetIOThreadTaskRunner({});
}
if (!background_task_runner.get()) {
diff --git a/chromium/content/browser/net/cross_origin_opener_policy_reporter.cc b/chromium/content/browser/net/cross_origin_opener_policy_reporter.cc
new file mode 100644
index 00000000000..59b0278c737
--- /dev/null
+++ b/chromium/content/browser/net/cross_origin_opener_policy_reporter.cc
@@ -0,0 +1,190 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/net/cross_origin_opener_policy_reporter.h"
+
+#include "base/values.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/public/browser/storage_partition.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+
+namespace content {
+
+namespace {
+
+constexpr char kUnsafeNone[] = "unsafe-none";
+constexpr char kSameOrigin[] = "same-origin";
+constexpr char kSameOriginPlusCoep[] = "same-origin-plus-coep";
+constexpr char kSameOriginAllowPopups[] = "same-origin-allow-popups";
+
+constexpr char kDisposition[] = "disposition";
+constexpr char kDispositionEnforce[] = "enforce";
+constexpr char kDispositionReporting[] = "reporting";
+constexpr char kDocumentURI[] = "document-uri";
+constexpr char kNavigationURI[] = "navigation-uri";
+constexpr char kViolationType[] = "violation-type";
+constexpr char kViolationTypeFromDocument[] = "navigation-from-document";
+constexpr char kViolationTypeToDocument[] = "navigation-to-document";
+constexpr char kEffectivePolicy[] = "effective-policy";
+
+std::string CoopValueToString(
+ network::mojom::CrossOriginOpenerPolicyValue coop_value,
+ network::mojom::CrossOriginEmbedderPolicyValue coep_value,
+ network::mojom::CrossOriginEmbedderPolicyValue report_only_coep_value) {
+ switch (coop_value) {
+ case network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone:
+ return kUnsafeNone;
+ case network::mojom::CrossOriginOpenerPolicyValue::kSameOrigin:
+ if ((coep_value ==
+ network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp) ||
+ (report_only_coep_value ==
+ network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp)) {
+ return kSameOriginPlusCoep;
+ }
+ return kSameOrigin;
+ case network::mojom::CrossOriginOpenerPolicyValue::kSameOriginAllowPopups:
+ return kSameOriginAllowPopups;
+ }
+}
+
+RenderFrameHostImpl* GetSourceRfhForCoopReporting(
+ RenderFrameHostImpl* current_rfh) {
+ CHECK(current_rfh);
+
+ // If this is a fresh popup we would consider the source RFH to be
+ // our opener.
+ // TODO(arthursonzogni): There seems to be no guarantee that opener() is
+ // always set, do we need to be more cautious here?
+ if (!current_rfh->has_committed_any_navigation())
+ return current_rfh->frame_tree_node()->opener()->current_frame_host();
+
+ // Otherwise this is simply the current RFH.
+ return current_rfh;
+}
+
+} // namespace
+
+CrossOriginOpenerPolicyReporter::CrossOriginOpenerPolicyReporter(
+ StoragePartition* storage_partition,
+ RenderFrameHostImpl* current_rfh,
+ const GURL& context_url,
+ const network::CrossOriginOpenerPolicy& coop,
+ const network::CrossOriginEmbedderPolicy& coep)
+ : storage_partition_(storage_partition),
+ context_url_(context_url),
+ coop_(coop),
+ coep_(coep) {
+ DCHECK(storage_partition_);
+ RenderFrameHostImpl* source_rfh = GetSourceRfhForCoopReporting(current_rfh);
+ source_url_ = source_rfh->GetLastCommittedURL();
+ source_routing_id_ = source_rfh->GetGlobalFrameRoutingId();
+}
+
+CrossOriginOpenerPolicyReporter::CrossOriginOpenerPolicyReporter(
+ StoragePartition* storage_partition,
+ const GURL& source_url,
+ const GlobalFrameRoutingId source_routing_id,
+ const GURL& context_url,
+ const network::CrossOriginOpenerPolicy& coop,
+ const network::CrossOriginEmbedderPolicy& coep)
+ : storage_partition_(storage_partition),
+ source_url_(source_url),
+ source_routing_id_(source_routing_id),
+ context_url_(context_url),
+ coop_(coop),
+ coep_(coep) {
+ DCHECK(storage_partition_);
+}
+
+CrossOriginOpenerPolicyReporter::~CrossOriginOpenerPolicyReporter() = default;
+
+void CrossOriginOpenerPolicyReporter::QueueOpenerBreakageReport(
+ const GURL& other_url,
+ bool is_reported_from_document,
+ bool is_report_only) {
+ const base::Optional<std::string>& endpoint =
+ is_report_only ? coop_.report_only_reporting_endpoint
+ : coop_.reporting_endpoint;
+ DCHECK(endpoint);
+
+ url::Replacements<char> replacements;
+ replacements.ClearUsername();
+ replacements.ClearPassword();
+ std::string sanitized_context_url =
+ context_url_.ReplaceComponents(replacements).spec();
+ std::string sanitized_other_url =
+ other_url.ReplaceComponents(replacements).spec();
+ base::DictionaryValue body;
+ body.SetString(kDisposition,
+ is_report_only ? kDispositionReporting : kDispositionEnforce);
+ body.SetString(kDocumentURI, sanitized_context_url);
+ body.SetString(kNavigationURI, sanitized_other_url);
+ body.SetString(kViolationType, is_reported_from_document
+ ? kViolationTypeFromDocument
+ : kViolationTypeToDocument);
+ body.SetString(
+ kEffectivePolicy,
+ CoopValueToString(is_report_only ? coop_.report_only_value : coop_.value,
+ coep_.value, coep_.report_only_value));
+ storage_partition_->GetNetworkContext()->QueueReport(
+ "coop", *endpoint, context_url_, /*user_agent=*/base::nullopt,
+ std::move(body));
+}
+
+void CrossOriginOpenerPolicyReporter::Clone(
+ mojo::PendingReceiver<network::mojom::CrossOriginOpenerPolicyReporter>
+ receiver) {
+ receiver_set_.Add(this, std::move(receiver));
+}
+
+GURL CrossOriginOpenerPolicyReporter::GetPreviousDocumentUrlForReporting(
+ const std::vector<GURL>& redirect_chain,
+ const GURL& referrer_url) {
+ // If the current document and all its redirect chain are same-origin with
+ // the previous document, this is the previous document URL.
+ auto source_origin = url::Origin::Create(source_url_);
+ bool is_redirect_chain_same_origin = true;
+ for (auto& redirect_url : redirect_chain) {
+ auto redirect_origin = url::Origin::Create(redirect_url);
+ if (!redirect_origin.IsSameOriginWith(source_origin)) {
+ is_redirect_chain_same_origin = false;
+ break;
+ }
+ }
+ if (is_redirect_chain_same_origin)
+ return source_url_;
+
+ // Otherwise, it's the referrer of the navigation.
+ return referrer_url;
+}
+
+GURL CrossOriginOpenerPolicyReporter::GetNextDocumentUrlForReporting(
+ const std::vector<GURL>& redirect_chain,
+ const GlobalFrameRoutingId& initiator_routing_id) {
+ const url::Origin& source_origin = url::Origin::Create(source_url_);
+
+ // If the next document and all its redirect chain are same-origin with the
+ // current document, this is the next document URL.
+ bool is_redirect_chain_same_origin = true;
+ for (auto& redirect_url : redirect_chain) {
+ auto redirect_origin = url::Origin::Create(redirect_url);
+ if (!redirect_origin.IsSameOriginWith(source_origin)) {
+ is_redirect_chain_same_origin = false;
+ break;
+ }
+ }
+ if (is_redirect_chain_same_origin)
+ return redirect_chain[redirect_chain.size() - 1];
+
+ // If the current document is the initiator of the navigation, then it's the
+ // initial navigation URL.
+ if (source_routing_id_ == initiator_routing_id)
+ return redirect_chain[0];
+
+ // Otherwise, it's the empty URL.
+ return GURL();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/net/cross_origin_opener_policy_reporter.h b/chromium/content/browser/net/cross_origin_opener_policy_reporter.h
new file mode 100644
index 00000000000..db91781e89c
--- /dev/null
+++ b/chromium/content/browser/net/cross_origin_opener_policy_reporter.h
@@ -0,0 +1,95 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_NET_CROSS_ORIGIN_OPENER_POLICY_REPORTER_H_
+#define CONTENT_BROWSER_NET_CROSS_ORIGIN_OPENER_POLICY_REPORTER_H_
+
+#include <string>
+
+#include "base/optional.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/global_routing_id.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "services/network/public/mojom/cross_origin_embedder_policy.mojom.h"
+#include "services/network/public/mojom/cross_origin_opener_policy.mojom.h"
+#include "url/gurl.h"
+
+namespace content {
+
+class StoragePartition;
+class RenderFrameHostImpl;
+
+// Used to report (potential) COOP breakages.
+// A CrossOriginOpenerPolicyReporter lives in the browser process and is either
+// held by the NavigationRequest during navigation or by the RenderFrameHostImpl
+// after the document has committed.
+// To make calls from other processes, create a mojo endpoint using Clone and
+// pass the receiver to other processes.
+// Any functions other than the destructor must not be called after the
+// associated StoragePartition is destructed.
+class CONTENT_EXPORT CrossOriginOpenerPolicyReporter final
+ : public network::mojom::CrossOriginOpenerPolicyReporter {
+ public:
+ CrossOriginOpenerPolicyReporter(
+ StoragePartition* storage_partition,
+ RenderFrameHostImpl* current_frame_host,
+ const GURL& context_url,
+ const network::CrossOriginOpenerPolicy& coop,
+ const network::CrossOriginEmbedderPolicy& coep);
+ ~CrossOriginOpenerPolicyReporter() override;
+ CrossOriginOpenerPolicyReporter(const CrossOriginOpenerPolicyReporter&) =
+ delete;
+ CrossOriginOpenerPolicyReporter& operator=(
+ const CrossOriginOpenerPolicyReporter&) = delete;
+
+ // network::mojom::CrossOriginOpenerPolicyReporter implementation.
+ void QueueOpenerBreakageReport(const GURL& other_url,
+ bool is_reported_from_document,
+ bool is_report_only) override;
+
+ // Returns the "previous" URL that is safe to expose.
+ // Reference, "Next document URL for reporting" section:
+ // https://github.com/camillelamy/explainers/blob/master/coop_reporting.md#safe-urls-for-reporting
+ GURL GetPreviousDocumentUrlForReporting(
+ const std::vector<GURL>& redirect_chain,
+ const GURL& referrer_url);
+
+ // Returns the "next" URL that is safe to expose.
+ // Reference, "Next document URL for reporting" section:
+ // https://github.com/camillelamy/explainers/blob/master/coop_reporting.md#safe-urls-for-reporting
+ GURL GetNextDocumentUrlForReporting(
+ const std::vector<GURL>& redirect_chain,
+ const GlobalFrameRoutingId& initiator_routing_id);
+
+ void Clone(
+ mojo::PendingReceiver<network::mojom::CrossOriginOpenerPolicyReporter>
+ receiver) override;
+
+ private:
+ friend class CrossOriginOpenerPolicyReporterTest;
+
+ // Used in unit_tests that do not have access to a RenderFrameHost.
+ CrossOriginOpenerPolicyReporter(
+ StoragePartition* storage_partition,
+ const GURL& source_url,
+ const GlobalFrameRoutingId source_routing_id,
+ const GURL& context_url,
+ const network::CrossOriginOpenerPolicy& coop,
+ const network::CrossOriginEmbedderPolicy& coep);
+
+ // See the class comment.
+ StoragePartition* const storage_partition_;
+ GURL source_url_;
+ GlobalFrameRoutingId source_routing_id_;
+ const GURL context_url_;
+ network::CrossOriginOpenerPolicy coop_;
+ network::CrossOriginEmbedderPolicy coep_;
+
+ mojo::ReceiverSet<network::mojom::CrossOriginOpenerPolicyReporter>
+ receiver_set_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_NET_CROSS_ORIGIN_OPENER_POLICY_REPORTER_H_
diff --git a/chromium/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc b/chromium/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc
new file mode 100644
index 00000000000..b4e9bb3f13e
--- /dev/null
+++ b/chromium/content/browser/net/cross_origin_opener_policy_reporter_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/net/cross_origin_opener_policy_reporter.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/test/task_environment.h"
+#include "base/values.h"
+#include "content/public/test/test_storage_partition.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/network/test/test_network_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class TestNetworkContext : public network::TestNetworkContext {
+ public:
+ struct Report {
+ Report(const std::string& type,
+ const std::string& group,
+ const GURL& url,
+ base::Value body)
+ : type(type), group(group), url(url), body(std::move(body)) {}
+
+ std::string type;
+ std::string group;
+ GURL url;
+ base::Value body;
+ };
+ void QueueReport(const std::string& type,
+ const std::string& group,
+ const GURL& url,
+ const base::Optional<std::string>& user_agent,
+ base::Value body) override {
+ DCHECK(!user_agent);
+ reports_.emplace_back(Report(type, group, url, std::move(body)));
+ }
+
+ const std::vector<Report>& reports() const { return reports_; }
+
+ private:
+ std::vector<Report> reports_;
+};
+
+} // namespace
+
+class CrossOriginOpenerPolicyReporterTest : public testing::Test {
+ public:
+ using Report = TestNetworkContext::Report;
+ CrossOriginOpenerPolicyReporterTest() {
+ storage_partition_.set_network_context(&network_context_);
+ coop_.value = network::mojom::CrossOriginOpenerPolicyValue::kSameOrigin;
+ coep_.value = network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
+ coop_.reporting_endpoint = "e1";
+ context_url_ = GURL("https://www1.example.com/x");
+ }
+
+ StoragePartition* storage_partition() { return &storage_partition_; }
+ const TestNetworkContext& network_context() const { return network_context_; }
+ const GURL& context_url() const { return context_url_; }
+ const network::CrossOriginOpenerPolicy& coop() const { return coop_; }
+ const network::CrossOriginEmbedderPolicy& coep() const { return coep_; }
+
+ protected:
+ std::unique_ptr<CrossOriginOpenerPolicyReporter> GetReporter() {
+ return std::unique_ptr<CrossOriginOpenerPolicyReporter>(
+ new CrossOriginOpenerPolicyReporter(storage_partition(), GURL(),
+ GlobalFrameRoutingId(123, 456),
+ context_url(), coop(), coep()));
+ }
+
+ private:
+ base::test::TaskEnvironment task_environment_;
+ TestNetworkContext network_context_;
+ TestStoragePartition storage_partition_;
+ GURL context_url_;
+ network::CrossOriginOpenerPolicy coop_;
+ network::CrossOriginEmbedderPolicy coep_;
+};
+
+TEST_F(CrossOriginOpenerPolicyReporterTest, Basic) {
+ auto reporter = GetReporter();
+
+ reporter->QueueOpenerBreakageReport(
+ GURL("https://www1.example.com/y#foo?bar=baz"), false, false);
+ reporter->QueueOpenerBreakageReport(GURL("http://www2.example.com:41/z"),
+ true, false);
+
+ ASSERT_EQ(2u, network_context().reports().size());
+ const Report& r1 = network_context().reports()[0];
+ const Report& r2 = network_context().reports()[1];
+
+ EXPECT_EQ(r1.type, "coop");
+ EXPECT_EQ(r1.body.FindKey("disposition")->GetString(), "enforce");
+ EXPECT_EQ(r1.body.FindKey("document-uri")->GetString(), context_url());
+ EXPECT_EQ(r1.body.FindKey("navigation-uri")->GetString(),
+ "https://www1.example.com/y#foo?bar=baz");
+ EXPECT_EQ(r1.body.FindKey("violation-type")->GetString(),
+ "navigation-to-document");
+ EXPECT_EQ(r1.body.FindKey("effective-policy")->GetString(),
+ "same-origin-plus-coep");
+
+ EXPECT_EQ(r2.type, "coop");
+ EXPECT_EQ(r2.body.FindKey("disposition")->GetString(), "enforce");
+ EXPECT_EQ(r2.body.FindKey("document-uri")->GetString(), context_url());
+ EXPECT_EQ(r2.body.FindKey("navigation-uri")->GetString(),
+ "http://www2.example.com:41/z");
+ EXPECT_EQ(r2.body.FindKey("violation-type")->GetString(),
+ "navigation-from-document");
+ EXPECT_EQ(r2.body.FindKey("effective-policy")->GetString(),
+ "same-origin-plus-coep");
+}
+
+TEST_F(CrossOriginOpenerPolicyReporterTest, UserAndPassSanitization) {
+ auto reporter = GetReporter();
+
+ reporter->QueueOpenerBreakageReport(GURL("https://u:p@www2.example.com/x"),
+ false, false);
+
+ ASSERT_EQ(1u, network_context().reports().size());
+ const Report& r1 = network_context().reports()[0];
+
+ EXPECT_EQ(r1.type, "coop");
+ EXPECT_EQ(r1.body.FindKey("document-uri")->GetString(),
+ "https://www1.example.com/x");
+ EXPECT_EQ(r1.body.FindKey("navigation-uri")->GetString(),
+ "https://www2.example.com/x");
+}
+
+TEST_F(CrossOriginOpenerPolicyReporterTest, Clone) {
+ auto reporter = GetReporter();
+
+ mojo::Remote<network::mojom::CrossOriginOpenerPolicyReporter> remote;
+ reporter->Clone(remote.BindNewPipeAndPassReceiver());
+
+ remote->QueueOpenerBreakageReport(GURL("https://www1.example.com/y"), false,
+ false);
+
+ remote.FlushForTesting();
+
+ ASSERT_EQ(1u, network_context().reports().size());
+ const Report& r1 = network_context().reports()[0];
+
+ EXPECT_EQ(r1.type, "coop");
+ EXPECT_EQ(r1.body.FindKey("disposition")->GetString(), "enforce");
+ EXPECT_EQ(r1.body.FindKey("document-uri")->GetString(), context_url());
+ EXPECT_EQ(r1.body.FindKey("navigation-uri")->GetString(),
+ "https://www1.example.com/y");
+ EXPECT_EQ(r1.body.FindKey("violation-type")->GetString(),
+ "navigation-to-document");
+ EXPECT_EQ(r1.body.FindKey("effective-policy")->GetString(),
+ "same-origin-plus-coep");
+}
+
+} // namespace content
diff --git a/chromium/content/browser/net/network_errors_listing_ui.cc b/chromium/content/browser/net/network_errors_listing_ui.cc
index b892365db3e..c34768990ae 100644
--- a/chromium/content/browser/net/network_errors_listing_ui.cc
+++ b/chromium/content/browser/net/network_errors_listing_ui.cc
@@ -29,13 +29,12 @@ namespace content {
namespace {
std::unique_ptr<base::ListValue> GetNetworkErrorData() {
- std::unique_ptr<base::DictionaryValue> error_codes = net::GetNetConstants();
+ base::Value error_codes = net::GetNetConstants();
const base::DictionaryValue* net_error_codes_dict = nullptr;
- for (base::DictionaryValue::Iterator itr(*error_codes); !itr.IsAtEnd();
- itr.Advance()) {
- if (itr.key() == kNetworkErrorKey) {
- itr.value().GetAsDictionary(&net_error_codes_dict);
+ for (const auto& item : error_codes.DictItems()) {
+ if (item.first == kNetworkErrorKey) {
+ item.second.GetAsDictionary(&net_error_codes_dict);
break;
}
}