summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSohom <dattasohom1@gmail.com>2023-01-20 15:20:52 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-04-03 15:23:54 +0000
commit10ed81d38083ad3061ef163dd2c3b089c385590f (patch)
treee6afc6c186f70512d850bfa5513461cd5de836cf
parent0487d1dcb21e3c931cb5b1185b6419740570ab25 (diff)
downloadqtwebengine-chromium-10ed81d38083ad3061ef163dd2c3b089c385590f.tar.gz
[Backport] CVE-2023-1232: Insufficient policy enforcement in Resource Timing
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/3976688: Report ResourceTiming entries for 204/205 status codes even when not navigating Bug: 1346924 Change-Id: I368885b3dfaa5647795f08213d410861114c1dfa Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3976688 Reviewed-by: Emily Stark <estark@chromium.org> Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org> Commit-Queue: Sohom Datta <dattasohom1@gmail.com> Cr-Commit-Position: refs/heads/main@{#1095047} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/468202 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/content/browser/BUILD.gn2
-rw-r--r--chromium/content/browser/loader/object_navigation_fallback_body_loader.cc148
-rw-r--r--chromium/content/browser/loader/resource_timing_utils.cc103
-rw-r--r--chromium/content/browser/loader/resource_timing_utils.h25
-rw-r--r--chromium/content/browser/renderer_host/navigation_request.cc40
-rw-r--r--chromium/content/browser/renderer_host/navigation_request.h8
-rw-r--r--chromium/content/public/common/content_features.cc6
-rw-r--r--chromium/content/public/common/content_features.h2
-rw-r--r--chromium/third_party/blink/common/BUILD.gn1
-rw-r--r--chromium/third_party/blink/common/frame/frame_owner_element_type_mojom_traits.cc65
-rw-r--r--chromium/third_party/blink/public/common/BUILD.gn1
-rw-r--r--chromium/third_party/blink/public/common/frame/frame_owner_element_type_mojom_traits.h22
-rw-r--r--chromium/third_party/blink/public/mojom/BUILD.gn9
-rw-r--r--chromium/third_party/blink/public/mojom/frame/frame.mojom26
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.h5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h4
18 files changed, 368 insertions, 142 deletions
diff --git a/chromium/content/browser/BUILD.gn b/chromium/content/browser/BUILD.gn
index 3cd5feb4203..2e42331adbb 100644
--- a/chromium/content/browser/BUILD.gn
+++ b/chromium/content/browser/BUILD.gn
@@ -1208,6 +1208,8 @@ jumbo_source_set("browser") {
"loader/prefetch_url_loader.h",
"loader/prefetch_url_loader_service.cc",
"loader/prefetch_url_loader_service.h",
+ "loader/resource_timing_utils.cc",
+ "loader/resource_timing_utils.h",
"loader/shared_cors_origin_access_list_impl.cc",
"loader/shared_cors_origin_access_list_impl.h",
"loader/single_request_url_loader_factory.cc",
diff --git a/chromium/content/browser/loader/object_navigation_fallback_body_loader.cc b/chromium/content/browser/loader/object_navigation_fallback_body_loader.cc
index 7389d290e54..cbaf2723d4d 100644
--- a/chromium/content/browser/loader/object_navigation_fallback_body_loader.cc
+++ b/chromium/content/browser/loader/object_navigation_fallback_body_loader.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/containers/contains.h"
+#include "content/browser/loader/resource_timing_utils.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
@@ -32,145 +33,6 @@ namespace content {
namespace {
-// This logic is duplicated from Performance::PassesTimingAllowCheck. Ensure
-// that any changes are synced between both copies.
-bool PassesTimingAllowCheck(
- const network::mojom::URLResponseHead& response_head,
- const GURL& url,
- const GURL& next_url,
- const url::Origin& parent_origin,
- bool& response_tainting_not_basic,
- bool& tainted_origin_flag) {
- const url::Origin response_origin = url::Origin::Create(url);
- const bool is_same_origin = response_origin.IsSameOriginWith(parent_origin);
- // Still same-origin and resource tainting is "basic": just return true.
- if (!response_tainting_not_basic && is_same_origin) {
- return true;
- }
-
- // Otherwise, a cross-origin response is currently (or has previously) been
- // handled, so resource tainting is no longer "basic".
- response_tainting_not_basic = true;
-
- const network::mojom::TimingAllowOriginPtr& tao =
- response_head.parsed_headers->timing_allow_origin;
- if (!tao) {
- return false;
- }
-
- if (tao->which() == network::mojom::TimingAllowOrigin::Tag::kAll)
- return true;
-
- // TODO(https://crbug.com/1128402): For now, this bookkeeping only exists to
- // stay in sync with the Blink code.
- bool is_next_resource_same_origin = true;
- if (url != next_url) {
- is_next_resource_same_origin =
- response_origin.IsSameOriginWith(url::Origin::Create(next_url));
- }
-
- if (!is_same_origin && !is_next_resource_same_origin) {
- tainted_origin_flag = true;
- }
-
- return base::Contains(tao->get_serialized_origins(),
- parent_origin.Serialize());
-}
-
-// This logic is duplicated from Performance::AllowsTimingRedirect(). Ensure
-// that any changes are synced between both copies.
-//
-// TODO(https://crbug.com/1201767): There is a *third* implementation of the TAO
-// check in CorsURLLoader, but it exactly implements the TAO check as defined in
-// the Fetch standard. Unfortunately, the definition in the standard always
-// allows timing details for navigations: the response tainting is always
-// considered "basic" for navigations, which means that timing details will
-// always be allowed, even for cross-origin frames. Oops.
-bool AllowTimingDetailsForParent(
- const url::Origin& parent_origin,
- const blink::mojom::CommonNavigationParams& common_params,
- const blink::mojom::CommitNavigationParams& commit_params,
- const network::mojom::URLResponseHead& response_head) {
- bool response_tainting_not_basic = false;
- bool tainted_origin_flag = false;
-
- DCHECK_EQ(commit_params.redirect_infos.size(),
- commit_params.redirect_response.size());
- for (size_t i = 0; i < commit_params.redirect_infos.size(); ++i) {
- const GURL& next_response_url =
- i + 1 < commit_params.redirect_infos.size()
- ? commit_params.redirect_infos[i + 1].new_url
- : common_params.url;
- if (!PassesTimingAllowCheck(
- *commit_params.redirect_response[i],
- commit_params.redirect_infos[i].new_url, next_response_url,
- parent_origin, response_tainting_not_basic, tainted_origin_flag)) {
- return false;
- }
- }
-
- return PassesTimingAllowCheck(
- response_head, common_params.url, common_params.url, parent_origin,
- response_tainting_not_basic, tainted_origin_flag);
-}
-
-// This logic is duplicated from Performance::GenerateResourceTiming(). Ensure
-// that any changes are synced between both copies.
-blink::mojom::ResourceTimingInfoPtr GenerateResourceTiming(
- const url::Origin& parent_origin,
- const blink::mojom::CommonNavigationParams& common_params,
- const blink::mojom::CommitNavigationParams& commit_params,
- const network::mojom::URLResponseHead& response_head) {
- // TODO(dcheng): There should be a Blink helper for populating the timing info
- // that's exposed in //third_party/blink/common. This would allow a lot of the
- // boilerplate to be shared.
-
- auto timing_info = blink::mojom::ResourceTimingInfo::New();
- const GURL& initial_url = !commit_params.original_url.is_empty()
- ? commit_params.original_url
- : common_params.url;
- timing_info->name = initial_url.spec();
- timing_info->start_time = common_params.navigation_start;
- timing_info->alpn_negotiated_protocol =
- response_head.alpn_negotiated_protocol;
- timing_info->connection_info = net::HttpResponseInfo::ConnectionInfoToString(
- response_head.connection_info);
-
- // If there's no received headers end time, don't set load timing. This is the
- // case for non-HTTP requests, requests that don't go over the wire, and
- // certain error cases.
- // TODO(dcheng): Is it actually possible to hit this path if
- // `response_head.headers` is populated?
- if (!response_head.load_timing.receive_headers_end.is_null()) {
- timing_info->timing = response_head.load_timing;
- }
- // `response_end` will be populated after loading the body.
- timing_info->context_type = blink::mojom::RequestContextType::OBJECT;
-
- timing_info->allow_timing_details = AllowTimingDetailsForParent(
- parent_origin, common_params, commit_params, response_head);
-
- DCHECK_EQ(commit_params.redirect_infos.size(),
- commit_params.redirect_response.size());
-
- if (!commit_params.redirect_infos.empty()) {
- timing_info->allow_redirect_details = timing_info->allow_timing_details;
- timing_info->last_redirect_end_time =
- commit_params.redirect_response.back()->load_timing.receive_headers_end;
- } else {
- timing_info->allow_redirect_details = false;
- timing_info->last_redirect_end_time = base::TimeTicks();
- }
- // The final value for `encoded_body_size` and `decoded_body_size` will be
- // populated after loading the body.
- timing_info->did_reuse_connection = response_head.load_timing.socket_reused;
- // Use url::Origin to handle cases like blob:https://.
- timing_info->is_secure_transport = base::Contains(
- url::GetSecureSchemes(), url::Origin::Create(common_params.url).scheme());
- timing_info->allow_negative_values = false;
- return timing_info;
-}
-
std::string ExtractServerTimingValueIfNeeded(
const network::mojom::URLResponseHead& response_head) {
std::string value;
@@ -205,9 +67,11 @@ void ObjectNavigationFallbackBodyLoader::CreateAndStart(
// It's safe to snapshot the parent origin in the calculation here; if the
// parent frame navigates, `render_frame_host_` will be deleted, which
// triggers deletion of `this`, cancelling all remaining work.
- blink::mojom::ResourceTimingInfoPtr timing_info = GenerateResourceTiming(
- render_frame_host->GetParent()->GetLastCommittedOrigin(), common_params,
- commit_params, response_head);
+ blink::mojom::ResourceTimingInfoPtr timing_info =
+ GenerateResourceTimingForNavigation(
+ render_frame_host->GetParent()->GetLastCommittedOrigin(),
+ common_params, commit_params, response_head,
+ blink::mojom::RequestContextType::OBJECT);
std::string server_timing_value =
ExtractServerTimingValueIfNeeded(response_head);
diff --git a/chromium/content/browser/loader/resource_timing_utils.cc b/chromium/content/browser/loader/resource_timing_utils.cc
new file mode 100644
index 00000000000..f6ffc3fee68
--- /dev/null
+++ b/chromium/content/browser/loader/resource_timing_utils.cc
@@ -0,0 +1,103 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/resource_timing_utils.h"
+
+#include <string>
+#include <utility>
+
+#include "base/containers/contains.h"
+#include "net/http/http_response_info.h"
+#include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom.h"
+#include "url/gurl.h"
+#include "url/url_util.h"
+
+namespace {
+
+// Implements the TimingAllowOrigin check
+// This logic is duplicated from Performance::AllowsTimingRedirect(). Ensure
+// that any changes are synced between both copies.
+bool IsCrossOriginResponseOrHasCrossOriginRedirects(
+ const url::Origin& parent_origin,
+ const blink::mojom::CommonNavigationParams& common_params,
+ const blink::mojom::CommitNavigationParams& commit_params) {
+ DCHECK_EQ(commit_params.redirect_infos.size(),
+ commit_params.redirect_response.size());
+ for (const auto& info : commit_params.redirect_infos) {
+ if (!parent_origin.IsSameOriginWith(info.new_url)) {
+ return true;
+ }
+ }
+
+ return !parent_origin.IsSameOriginWith(common_params.url);
+}
+
+} // namespace
+
+namespace content {
+
+// This logic is duplicated from Performance::GenerateResourceTiming(). Ensure
+// that any changes are synced between both copies.
+blink::mojom::ResourceTimingInfoPtr GenerateResourceTimingForNavigation(
+ const url::Origin& parent_origin,
+ const blink::mojom::CommonNavigationParams& common_params,
+ const blink::mojom::CommitNavigationParams& commit_params,
+ const network::mojom::URLResponseHead& response_head,
+ blink::mojom::RequestContextType context_type) {
+ // TODO(dcheng): There should be a Blink helper for populating the timing info
+ // that's exposed in //chromium/third_party/blink/common. This would allow a lot of the
+ // boilerplate to be shared.
+
+ auto timing_info = blink::mojom::ResourceTimingInfo::New();
+ const GURL& initial_url = !commit_params.original_url.is_empty()
+ ? commit_params.original_url
+ : common_params.url;
+ timing_info->name = initial_url.spec();
+ timing_info->start_time = common_params.navigation_start;
+ timing_info->alpn_negotiated_protocol =
+ response_head.alpn_negotiated_protocol;
+ timing_info->connection_info = net::HttpResponseInfo::ConnectionInfoToString(
+ response_head.connection_info);
+
+ // If there's no received headers end time, don't set load timing. This is the
+ // case for non-HTTP requests, requests that don't go over the wire, and
+ // certain error cases.
+ // TODO(dcheng): Is it actually possible to hit this path if
+ // `response_head.headers` is populated?
+ if (!response_head.load_timing.receive_headers_end.is_null()) {
+ timing_info->timing = response_head.load_timing;
+ }
+ // `response_end` will be populated after loading the body.
+ timing_info->context_type = context_type;
+ timing_info->allow_timing_details = response_head.timing_allow_passed;
+
+ // Only expose the response code when the response tainting is "basic" -
+ // same-origin requests throughout the redirect chain
+ if (!IsCrossOriginResponseOrHasCrossOriginRedirects(
+ parent_origin, common_params, commit_params)) {
+ timing_info->response_status = commit_params.http_response_code;
+ }
+
+ DCHECK_EQ(commit_params.redirect_infos.size(),
+ commit_params.redirect_response.size());
+
+ if (!commit_params.redirect_infos.empty()) {
+ timing_info->allow_redirect_details = timing_info->allow_timing_details;
+ timing_info->last_redirect_end_time =
+ commit_params.redirect_response.back()->load_timing.receive_headers_end;
+ } else {
+ timing_info->allow_redirect_details = false;
+ timing_info->last_redirect_end_time = base::TimeTicks();
+ }
+ // The final value for `encoded_body_size` and `decoded_body_size` will be
+ // populated after loading the body.
+ timing_info->did_reuse_connection = response_head.load_timing.socket_reused;
+ // Use url::Origin to handle cases like blob:https://.
+ timing_info->is_secure_transport = base::Contains(
+ url::GetSecureSchemes(), url::Origin::Create(common_params.url).scheme());
+ timing_info->allow_negative_values = false;
+ return timing_info;
+}
+} // namespace content \ No newline at end of file
diff --git a/chromium/content/browser/loader/resource_timing_utils.h b/chromium/content/browser/loader/resource_timing_utils.h
new file mode 100644
index 00000000000..5fd32d4be51
--- /dev/null
+++ b/chromium/content/browser/loader/resource_timing_utils.h
@@ -0,0 +1,25 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_RESOURCE_TIMING_UTILS_H_
+#define CONTENT_BROWSER_LOADER_RESOURCE_TIMING_UTILS_H_
+
+#include "services/network/public/mojom/url_response_head.mojom-forward.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-forward.h"
+#include "third_party/blink/public/mojom/navigation/navigation_params.mojom-forward.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-forward.h"
+#include "url/origin.h"
+
+namespace content {
+
+blink::mojom::ResourceTimingInfoPtr GenerateResourceTimingForNavigation(
+ const url::Origin& parent_origin,
+ const blink::mojom::CommonNavigationParams& common_params,
+ const blink::mojom::CommitNavigationParams& commit_params,
+ const network::mojom::URLResponseHead& response_head,
+ blink::mojom::RequestContextType context_type);
+
+} // namespace content
+
+#endif
diff --git a/chromium/content/browser/renderer_host/navigation_request.cc b/chromium/content/browser/renderer_host/navigation_request.cc
index c46ed4d91ed..b20250eb0f1 100644
--- a/chromium/content/browser/renderer_host/navigation_request.cc
+++ b/chromium/content/browser/renderer_host/navigation_request.cc
@@ -23,6 +23,7 @@
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
+#include "base/notreached.h"
#include "base/rand_util.h"
#include "base/state_transitions.h"
#include "base/strings/strcat.h"
@@ -47,6 +48,7 @@
#include "content/browser/loader/navigation_early_hints_manager.h"
#include "content/browser/loader/navigation_url_loader.h"
#include "content/browser/loader/object_navigation_fallback_body_loader.h"
+#include "content/browser/loader/resource_timing_utils.h"
#include "content/browser/navigation_or_document_handle.h"
#include "content/browser/network/cross_origin_embedder_policy_reporter.h"
#include "content/browser/network/cross_origin_opener_policy_reporter.h"
@@ -168,6 +170,7 @@
#include "third_party/blink/public/mojom/navigation/prefetched_signed_exchange_info.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h"
#include "third_party/blink/public/mojom/storage_key/ancestor_chain_bit.mojom.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-forward.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h"
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
#include "ui/compositor/compositor_lock.h"
@@ -4548,6 +4551,42 @@ network::mojom::WebSandboxFlags NavigationRequest::SandboxFlagsToCommit() {
return policy_container_builder_->FinalPolicies().sandbox_flags;
}
+void NavigationRequest::MaybeAddResourceTimingEntryForCancelledNavigation() {
+ if (!base::FeatureList::IsEnabled(
+ features::kResourceTimingForCancelledNavigationInFrame)) {
+ return;
+ }
+
+ RenderFrameHostImpl* parent_rfh = GetParentFrame();
+
+ // Do not add ResourceTiming entries if the navigated URL does not have a
+ // parent.
+ if (!parent_rfh) {
+ return;
+ }
+
+ // Some navigation are cancelled even before requesting and receiving a
+ // response. Those cases are not supported and the ResourceTiming is not
+ // reported to the parent.
+ if (!response_head_) {
+ return;
+ }
+
+ if (initiator_document_.AsRenderFrameHostIfValid() != parent_rfh) {
+ return;
+ }
+
+ blink::mojom::ResourceTimingInfoPtr timing_info =
+ GenerateResourceTimingForNavigation(
+ parent_rfh->GetLastCommittedOrigin(), *common_params_,
+ *commit_params_, *response_head_, request_context_type());
+ timing_info->response_end = base::TimeTicks::Now();
+ parent_rfh->GetAssociatedLocalFrame()
+ ->AddResourceTimingEntryFromNonNavigatedFrame(
+ std::move(timing_info),
+ frame_tree_node()->frame_owner_element_type());
+}
+
void NavigationRequest::OnRedirectChecksComplete(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(result.action() != NavigationThrottle::DEFER);
@@ -4792,6 +4831,7 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL ||
!response_should_be_rendered_) {
+ MaybeAddResourceTimingEntryForCancelledNavigation();
// Reset the RenderFrameHost that had been computed for the commit of the
// navigation.
render_frame_host_ = nullptr;
diff --git a/chromium/content/browser/renderer_host/navigation_request.h b/chromium/content/browser/renderer_host/navigation_request.h
index dcdf1c2c4c6..3554b505726 100644
--- a/chromium/content/browser/renderer_host/navigation_request.h
+++ b/chromium/content/browser/renderer_host/navigation_request.h
@@ -525,6 +525,14 @@ class CONTENT_EXPORT NavigationRequest
// new process.
void ResetStateForSiteInstanceChange();
+ // If a navigation has been cancelled, and was initiated by the parent
+ // document, report it with the appropriate ResourceTiming entry information.
+ //
+ // The ResourceTiming entry may not be sent if the current frame
+ // does not have a parent, or if the navigation was cancelled before
+ // a request was made.
+ void MaybeAddResourceTimingEntryForCancelledNavigation();
+
// Lazily initializes and returns the mojo::NavigationClient interface used
// for commit.
mojom::NavigationClient* GetCommitNavigationClient();
diff --git a/chromium/content/public/common/content_features.cc b/chromium/content/public/common/content_features.cc
index 759d4f529f4..ca4dc1203c3 100644
--- a/chromium/content/public/common/content_features.cc
+++ b/chromium/content/public/common/content_features.cc
@@ -98,6 +98,12 @@ BASE_FEATURE(kBackForwardCache,
"BackForwardCache",
base::FEATURE_ENABLED_BY_DEFAULT);
+// Enables reporting ResourceTiming entries for document, who initiated a
+// cancelled navigation in one of their <iframe>.
+BASE_FEATURE(kResourceTimingForCancelledNavigationInFrame,
+ "ResourceTimingForCancelledNavigationInFrame",
+ base::FEATURE_ENABLED_BY_DEFAULT);
+
// Allows pages that created a MediaSession service to stay eligible for the
// back/forward cache.
BASE_FEATURE(kBackForwardCacheMediaSessionService,
diff --git a/chromium/content/public/common/content_features.h b/chromium/content/public/common/content_features.h
index a773f61f367..be3ab65b232 100644
--- a/chromium/content/public/common/content_features.h
+++ b/chromium/content/public/common/content_features.h
@@ -31,6 +31,8 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kAvoidUnnecessaryBeforeUnloadCheckPostTask);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kAvoidUnnecessaryBeforeUnloadCheckSync);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kBackgroundFetch);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kBackForwardCache);
+CONTENT_EXPORT BASE_DECLARE_FEATURE(
+ kResourceTimingForCancelledNavigationInFrame);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kBackForwardCacheMemoryControls);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kBackForwardCacheMediaSessionService);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kBlockInsecurePrivateNetworkRequests);
diff --git a/chromium/third_party/blink/common/BUILD.gn b/chromium/third_party/blink/common/BUILD.gn
index 272639aa093..096ac8b993f 100644
--- a/chromium/third_party/blink/common/BUILD.gn
+++ b/chromium/third_party/blink/common/BUILD.gn
@@ -136,6 +136,7 @@ jumbo_source_set("common") {
"fetch/fetch_api_request_body_mojom_traits.cc",
"frame/frame_ad_evidence.cc",
"frame/frame_ad_evidence_mojom_traits.cc",
+ "frame/frame_owner_element_type_mojom_traits.cc",
"frame/frame_policy.cc",
"frame/frame_policy_mojom_traits.cc",
"frame/frame_visual_properties.cc",
diff --git a/chromium/third_party/blink/common/frame/frame_owner_element_type_mojom_traits.cc b/chromium/third_party/blink/common/frame/frame_owner_element_type_mojom_traits.cc
new file mode 100644
index 00000000000..7650dd3ad1e
--- /dev/null
+++ b/chromium/third_party/blink/common/frame/frame_owner_element_type_mojom_traits.cc
@@ -0,0 +1,65 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/public/common/frame/frame_owner_element_type_mojom_traits.h"
+#include "base/notreached.h"
+#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
+#include "third_party/blink/public/mojom/frame/frame.mojom-shared.h"
+
+namespace mojo {
+
+blink::mojom::FrameOwnerElementType EnumTraits<
+ blink::mojom::FrameOwnerElementType,
+ blink::FrameOwnerElementType>::ToMojom(blink::FrameOwnerElementType input) {
+ switch (input) {
+ case blink::FrameOwnerElementType::kIframe:
+ return blink::mojom::FrameOwnerElementType::kIframe;
+ case blink::FrameOwnerElementType::kObject:
+ return blink::mojom::FrameOwnerElementType::kObject;
+ case blink::FrameOwnerElementType::kEmbed:
+ return blink::mojom::FrameOwnerElementType::kEmbed;
+ case blink::FrameOwnerElementType::kFrame:
+ return blink::mojom::FrameOwnerElementType::kFrame;
+ case blink::FrameOwnerElementType::kPortal:
+ return blink::mojom::FrameOwnerElementType::kPortal;
+ case blink::FrameOwnerElementType::kFencedframe:
+ return blink::mojom::FrameOwnerElementType::kFencedframe;
+ case blink::FrameOwnerElementType::kNone:
+ return blink::mojom::FrameOwnerElementType::kNone;
+ }
+ NOTREACHED();
+ return blink::mojom::FrameOwnerElementType::kFrame;
+}
+
+bool EnumTraits<blink::mojom::FrameOwnerElementType,
+ blink::FrameOwnerElementType>::
+ FromMojom(blink::mojom::FrameOwnerElementType input,
+ blink::FrameOwnerElementType* output) {
+ switch (input) {
+ case blink::mojom::FrameOwnerElementType::kIframe:
+ *output = blink::FrameOwnerElementType::kIframe;
+ return true;
+ case blink::mojom::FrameOwnerElementType::kObject:
+ *output = blink::FrameOwnerElementType::kObject;
+ return true;
+ case blink::mojom::FrameOwnerElementType::kEmbed:
+ *output = blink::FrameOwnerElementType::kEmbed;
+ return true;
+ case blink::mojom::FrameOwnerElementType::kFrame:
+ *output = blink::FrameOwnerElementType::kFrame;
+ return true;
+ case blink::mojom::FrameOwnerElementType::kPortal:
+ *output = blink::FrameOwnerElementType::kPortal;
+ return true;
+ case blink::mojom::FrameOwnerElementType::kFencedframe:
+ *output = blink::FrameOwnerElementType::kFencedframe;
+ return true;
+ case blink::mojom::FrameOwnerElementType::kNone:
+ *output = blink::FrameOwnerElementType::kFrame;
+ return false;
+ }
+ *output = blink::FrameOwnerElementType::kFrame;
+ return false;
+}
+} // namespace mojo
diff --git a/chromium/third_party/blink/public/common/BUILD.gn b/chromium/third_party/blink/public/common/BUILD.gn
index a1ec4a5129a..2495af4966d 100644
--- a/chromium/third_party/blink/public/common/BUILD.gn
+++ b/chromium/third_party/blink/public/common/BUILD.gn
@@ -139,6 +139,7 @@ source_set("headers") {
"frame/fenced_frame_sandbox_flags.h",
"frame/frame_ad_evidence.h",
"frame/frame_owner_element_type.h",
+ "frame/frame_owner_element_type_mojom_traits.h",
"frame/frame_policy.h",
"frame/frame_visual_properties.h",
"frame/from_ad_state.h",
diff --git a/chromium/third_party/blink/public/common/frame/frame_owner_element_type_mojom_traits.h b/chromium/third_party/blink/public/common/frame/frame_owner_element_type_mojom_traits.h
new file mode 100644
index 00000000000..bfc786ea42c
--- /dev/null
+++ b/chromium/third_party/blink/public/common/frame/frame_owner_element_type_mojom_traits.h
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_FRAME_OWNER_ELEMENT_TYPE_MOJOM_TRAITS_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_FRAME_OWNER_ELEMENT_TYPE_MOJOM_TRAITS_H_
+
+#include "third_party/blink/public/common/common_export.h"
+#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
+#include "third_party/blink/public/mojom/frame/frame.mojom-shared.h"
+
+namespace mojo {
+template <>
+struct BLINK_COMMON_EXPORT EnumTraits<blink::mojom::FrameOwnerElementType,
+ blink::FrameOwnerElementType> {
+ static blink::mojom::FrameOwnerElementType ToMojom(
+ blink::FrameOwnerElementType input);
+ static bool FromMojom(blink::mojom::FrameOwnerElementType input,
+ blink::FrameOwnerElementType* output);
+};
+} // namespace mojo
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_FRAME_OWNER_ELEMENT_TYPE_MOJOM_TRAITS_H_
diff --git a/chromium/third_party/blink/public/mojom/BUILD.gn b/chromium/third_party/blink/public/mojom/BUILD.gn
index 64d971565ed..8086871fdbd 100644
--- a/chromium/third_party/blink/public/mojom/BUILD.gn
+++ b/chromium/third_party/blink/public/mojom/BUILD.gn
@@ -503,6 +503,15 @@ mojom("mojom_platform") {
{
types = [
{
+ mojom = "blink.mojom.FrameOwnerElementType"
+ cpp = "::blink::FrameOwnerElementType"
+ },
+ ]
+ traits_headers = [ "//third_party/blink/public/common/frame/frame_owner_element_type_mojom_traits.h" ]
+ },
+ {
+ types = [
+ {
mojom = "blink.mojom.SHA256HashValue"
cpp = "::net::SHA256HashValue"
},
diff --git a/chromium/third_party/blink/public/mojom/frame/frame.mojom b/chromium/third_party/blink/public/mojom/frame/frame.mojom
index fdf74376972..b691331179e 100644
--- a/chromium/third_party/blink/public/mojom/frame/frame.mojom
+++ b/chromium/third_party/blink/public/mojom/frame/frame.mojom
@@ -146,6 +146,16 @@ enum TraverseCancelledReason {
kSandboxViolation,
};
+enum FrameOwnerElementType {
+ kNone,
+ kIframe,
+ kObject,
+ kEmbed,
+ kFrame,
+ kPortal,
+ kFencedframe
+};
+
// The maximum number of characters of the document's title that we're willing
// to accept in the browser process.
const uint16 kMaxTitleChars = 4096; // 4 * 1024;
@@ -618,6 +628,22 @@ interface LocalFrame {
=> (mojo_base.mojom.String16 content, uint32 start_offset,
uint32 end_offset);
+ // Report ResourceTiming information about cancelled navigation in iframe
+ // initiated from this document. This is required to prevent revealing
+ // information about the status codes to the parent frame. (See crbug.com/1346924)
+ //
+ // Example of cancelled navigations:
+ // - 204 - No Content
+ // - 205 - Reset Content
+ // - Extension blocking navigation (e.g. Ad blocker)
+ // - etc
+ //
+ // |parent_frame_element_type| is used on the blink side to determine the
+ // 'initiator_type' of the entry.
+ AddResourceTimingEntryFromNonNavigatedFrame(
+ ResourceTimingInfo timing,
+ blink.mojom.FrameOwnerElementType parent_frame_element_type);
+
// Creates an intervention report in the frame with contents |id| and
// |message|, returns once the report has been queued. |id| identifies the
// intervention that occurred. |message| is a human-readable string that
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.cc b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
index f5b84b6821f..d6dca121c99 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
@@ -179,6 +179,7 @@
#include "third_party/blink/renderer/core/script/classic_script.h"
#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/core/svg/svg_document_extensions.h"
+#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/platform/back_forward_cache_utils.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/source_location.h"
@@ -229,6 +230,28 @@ namespace blink {
namespace {
+const AtomicString& ConvertElementTypeToInitiatorType(
+ blink::FrameOwnerElementType frame_owner_elem_type) {
+ switch (frame_owner_elem_type) {
+ case blink::FrameOwnerElementType::kFrame:
+ return blink::html_names::kFrameTag.LocalName();
+ case blink::FrameOwnerElementType::kIframe:
+ return blink::html_names::kIFrameTag.LocalName();
+ case blink::FrameOwnerElementType::kObject:
+ return blink::html_names::kObjectTag.LocalName();
+ case blink::FrameOwnerElementType::kFencedframe:
+ return blink::html_names::kFencedframeTag.LocalName();
+ case blink::FrameOwnerElementType::kEmbed:
+ return blink::html_names::kEmbedTag.LocalName();
+ case blink::FrameOwnerElementType::kPortal:
+ return blink::html_names::kPortalTag.LocalName();
+ case blink::FrameOwnerElementType::kNone:
+ NOTREACHED();
+ }
+ NOTREACHED();
+ return blink::html_names::kFrameTag.LocalName();
+}
+
// Maintain a global (statically-allocated) hash map indexed by the the result
// of hashing the |frame_token| passed on creation of a LocalFrame object.
using LocalFramesByTokenMap = HeapHashMap<uint64_t, WeakMember<LocalFrame>>;
@@ -667,6 +690,16 @@ ClipPathPaintImageGenerator* LocalFrame::GetClipPathPaintImageGenerator() {
return local_root.clip_path_paint_image_generator_.Get();
}
+void LocalFrame::AddResourceTimingEntryFromNonNavigatedFrame(
+ mojom::blink::ResourceTimingInfoPtr timing,
+ blink::FrameOwnerElementType initiator_type) {
+ auto* local_dom_window = DomWindow();
+ DOMWindowPerformance::performance(*local_dom_window)
+ ->AddResourceTiming(std::move(timing),
+ ConvertElementTypeToInitiatorType(initiator_type),
+ local_dom_window);
+}
+
const SecurityContext* LocalFrame::GetSecurityContext() const {
return DomWindow() ? &DomWindow()->GetSecurityContext() : nullptr;
}
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.h b/chromium/third_party/blink/renderer/core/frame/local_frame.h
index fcb29bcadaa..fe739c6f015 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h
@@ -41,6 +41,7 @@
#include "services/device/public/mojom/device_posture_provider.mojom-blink-forward.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "third_party/blink/public/common/frame/frame_ad_evidence.h"
+#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/public/common/frame/transient_allow_fullscreen.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/back_forward_cache_not_restored_reasons.mojom-blink.h"
@@ -281,6 +282,10 @@ class CORE_EXPORT LocalFrame final
BoxShadowPaintImageGenerator* GetBoxShadowPaintImageGenerator();
ClipPathPaintImageGenerator* GetClipPathPaintImageGenerator();
+ void AddResourceTimingEntryFromNonNavigatedFrame(
+ mojom::blink::ResourceTimingInfoPtr timing,
+ blink::FrameOwnerElementType initiator_type);
+
// A local root is the root of a connected subtree that contains only
// LocalFrames. The local root is responsible for coordinating input, layout,
// et cetera for that subtree of frames.
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
index bf8890f93a3..463a5b2c2b2 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -16,11 +16,13 @@
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/media_player_action.mojom-blink.h"
#include "third_party/blink/public/mojom/opengraph/metadata.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink-forward.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/web_frame_serializer.h"
#include "third_party/blink/public/web/web_local_frame.h"
@@ -67,6 +69,7 @@
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/script/classic_script.h"
+#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/platform/mhtml/serialized_resource.h"
#include "third_party/blink/renderer/platform/widget/frame_widget.h"
@@ -753,6 +756,13 @@ void LocalFrameMojoHandler::RenderFallbackContentWithResourceTiming(
server_timing_value);
}
+void LocalFrameMojoHandler::AddResourceTimingEntryFromNonNavigatedFrame(
+ mojom::blink::ResourceTimingInfoPtr timing,
+ blink::FrameOwnerElementType parent_frame_owner_element_type) {
+ frame_->AddResourceTimingEntryFromNonNavigatedFrame(
+ std::move(timing), parent_frame_owner_element_type);
+}
+
void LocalFrameMojoHandler::BeforeUnload(bool is_reload,
BeforeUnloadCallback callback) {
base::TimeTicks before_unload_start_time = base::TimeTicks::Now();
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h b/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h
index 64ce6036d3f..50306685ebe 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h
@@ -12,6 +12,7 @@
#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
#include "third_party/blink/public/mojom/media/fullscreen_video_element.mojom-blink.h"
#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
@@ -119,6 +120,9 @@ class LocalFrameMojoHandler
void RenderFallbackContentWithResourceTiming(
mojom::blink::ResourceTimingInfoPtr timing,
const String& server_timing_values) final;
+ void AddResourceTimingEntryFromNonNavigatedFrame(
+ mojom::blink::ResourceTimingInfoPtr timing,
+ blink::FrameOwnerElementType parent_frame_owner_element_type) final;
void BeforeUnload(bool is_reload, BeforeUnloadCallback callback) final;
void MediaPlayerActionAt(
const gfx::Point& window_point,