--- a/chrome/browser/webshare/share_service_impl.cc +++ b/chrome/browser/webshare/share_service_impl.cc @@ -19,6 +19,7 @@ #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom.h" +#include "url/url_constants.h" #if BUILDFLAG(IS_MAC) #include "chrome/browser/webshare/mac/sharing_service_operation.h" @@ -182,6 +183,25 @@ void ShareServiceImpl::Share(const std::string& title, return; } + // SECURITY: A well-behaved renderer enforces a scheme check at + // third_party/blink/renderer/modules/webshare/navigator_share.cc:93-103 + // (HTTP-family OR same scheme as the document). Re-enforce here so a + // compromised renderer cannot smuggle file://, chrome://, javascript://, + // etc. through to platform sinks. On macOS 13+ the URL is converted to a + // typed file:// NSURL and handed to NSSharingServicePicker, which would + // otherwise let share targets read arbitrary local files from the + // unsandboxed browser process. + if (!share_url.is_empty()) { + const GURL& frame_url = render_frame_host().GetLastCommittedURL(); + if (!share_url.SchemeIsHTTPOrHTTPS() && + share_url.scheme() != frame_url.scheme()) { + std::move(callback).Run(blink::mojom::ShareError::PERMISSION_DENIED); + ReportBadMessageAndDeleteThis( + "ShareService::Share received URL with disallowed scheme"); + return; + } + } + content::WebContents* const web_contents = content::WebContents::FromRenderFrameHost(&render_frame_host()); if (!web_contents) {