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 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. Upstream bug https://bugs.chromium.org/p/chromium/issues/detail?id=1081397. Upstreamed at https://chromium-review.googlesource.com/c/chromium/src/+/3856266. diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index d8424716274ca958bdfee87ac39a2cbbd1789a20..ba42acb1f85ae96a39654aaf61e7c5f11a8fb500 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc @@ -10737,6 +10737,12 @@ NavigationRequest::GetOriginForURLLoaderFactoryUncheckedWithDebugInfo() { } } + if (!common_params().url.IsStandard()) { + 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 2c9efc43b52219f8e2875e838819180c4995ee2b..88f13d06cac5e592d60fa9a26c7ccf3c152d722e 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc @@ -2253,6 +2253,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 @@ -2305,6 +2309,10 @@ scoped_refptr DocumentLoader::CalculateOrigin( debug_info_builder.Append(", url="); debug_info_builder.Append(owner_document->Url().BaseAsString()); debug_info_builder.Append(")"); + } 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