From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Mon, 29 Aug 2022 11:44:57 +0200 Subject: fix: crash loading non-standard schemes in iframes This fixes a crash that occurs when loading non-standard schemes from iframes or webviews. This was happening because ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin contains explicit exceptions to allow built-in non-standard schemes, but does not check for non-standard schemes registered by the embedder. This patch adjusts the origin calculation for subframe non-standard schemes in - browser process at `NavigationRequest::GetOriginForURLLoaderFactoryUncheckedWithDebugInfo` - render process at `DocumentLoader::CalculateOrigin` When top level frame navigates to non-standard scheme url, the origin is calculated as `null` without any derivation. It is only in cases where there is a `initiator_origin` then the origin is derived from it, which is usually the case for renderer initiated navigations and iframes are no exceptions from this rule. The patch should be removed in favor of either: - Remove support for non-standard custom schemes - Register non-standard custom schemes as websafe schemes and update CPSPI::CanAccessDataForOrigin to allow them for any navigation. - Update the callsite to use RFHI::CanCommitOriginAndUrl in upstream, previous effort to do this can be found at https://chromium-review.googlesource.com/c/chromium/src/+/3856266. Upstream bug https://bugs.chromium.org/p/chromium/issues/detail?id=1081397. diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 8c4070309b4a1072496e3e55f6f530a52a799451..afd62da2e140da715d9be15eb5c93f0339f59145 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc @@ -11048,6 +11048,12 @@ NavigationRequest::GetOriginForURLLoaderFactoryUncheckedWithDebugInfo() { "blob"); } + if (!common_params().url.IsStandard() && !common_params().url.IsAboutBlank()) { + return std::make_pair(url::Origin::Resolve(common_params().url, + url::Origin()), + "url_non_standard"); + } + // In cases not covered above, URLLoaderFactory should be associated with the // origin of |common_params.url| and/or |common_params.initiator_origin|. url::Origin resolved_origin = url::Origin::Resolve( diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 0c7b5af098a53a8709cdf62d455520ccef222dbb..1b6a7942c1506abc2fbe7d1efe58c0964a4e3be0 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc @@ -2336,6 +2336,10 @@ Frame* DocumentLoader::CalculateOwnerFrame() { scoped_refptr DocumentLoader::CalculateOrigin( Document* owner_document) { scoped_refptr origin; + bool is_standard = false; + std::string protocol = url_.Protocol().Ascii(); + is_standard = url::IsStandard( + protocol.data(), url::Component(0, static_cast(protocol.size()))); StringBuilder debug_info_builder; // Whether the origin is newly created within this call, instead of copied // from an existing document's origin or from `origin_to_commit_`. If this is @@ -2389,6 +2393,10 @@ scoped_refptr DocumentLoader::CalculateOrigin( // the end of this function. origin = origin_to_commit_; debug_info_builder.Append("use_origin_to_commit"); + } else if (!SecurityOrigin::ShouldUseInnerURL(url_) && + !is_standard) { + debug_info_builder.Append("use_url_with_non_standard_scheme"); + origin = SecurityOrigin::Create(url_); } else { debug_info_builder.Append("use_url_with_precursor"); // Otherwise, create an origin that propagates precursor information