Commit 6cb099a0 authored by Patrick Monette's avatar Patrick Monette Committed by Commit Bot

Enforce same-origin policy for shared workers in the browser process

Bug: 1004324
Change-Id: I85a80a8d590c44f2f23659bbafb79c6c3b83e059
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1804513
Commit-Queue: Patrick Monette <pmonette@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697723}
parent 42dc014d
...@@ -2446,6 +2446,17 @@ bool ChromeContentBrowserClient::AllowSharedWorker( ...@@ -2446,6 +2446,17 @@ bool ChromeContentBrowserClient::AllowSharedWorker(
return allow; return allow;
} }
bool ChromeContentBrowserClient::DoesSchemeAllowCrossOriginSharedWorker(
const std::string& scheme) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Extensions are allowed to start cross-origin shared workers.
if (scheme == extensions::kExtensionScheme)
return true;
#endif
return false;
}
bool ChromeContentBrowserClient::AllowSignedExchange( bool ChromeContentBrowserClient::AllowSignedExchange(
content::BrowserContext* browser_context) { content::BrowserContext* browser_context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
......
...@@ -238,6 +238,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { ...@@ -238,6 +238,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
content::BrowserContext* context, content::BrowserContext* context,
int render_process_id, int render_process_id,
int render_frame_id) override; int render_frame_id) override;
bool DoesSchemeAllowCrossOriginSharedWorker(
const std::string& scheme) override;
bool AllowSignedExchange(content::BrowserContext* browser_context) override; bool AllowSignedExchange(content::BrowserContext* browser_context) override;
void AllowWorkerFileSystem( void AllowWorkerFileSystem(
const GURL& url, const GURL& url,
......
...@@ -117,11 +117,23 @@ void SharedWorkerServiceImpl::ConnectToWorker( ...@@ -117,11 +117,23 @@ void SharedWorkerServiceImpl::ConnectToWorker(
return; return;
} }
// Enforce same-origin policy.
// data: URLs are not considered a different origin.
url::Origin constructor_origin = render_frame_host->GetLastCommittedOrigin();
bool is_cross_origin = !info->url.SchemeIs(url::kDataScheme) &&
url::Origin::Create(info->url) != constructor_origin;
if (is_cross_origin &&
!GetContentClient()->browser()->DoesSchemeAllowCrossOriginSharedWorker(
constructor_origin.scheme())) {
ScriptLoadFailed(std::move(client));
return;
}
RenderFrameHost* main_frame = RenderFrameHost* main_frame =
render_frame_host->frame_tree_node()->frame_tree()->GetMainFrame(); render_frame_host->frame_tree_node()->frame_tree()->GetMainFrame();
if (!GetContentClient()->browser()->AllowSharedWorker( if (!GetContentClient()->browser()->AllowSharedWorker(
info->url, main_frame->GetLastCommittedURL(), info->name, info->url, main_frame->GetLastCommittedURL(), info->name,
render_frame_host->GetLastCommittedOrigin(), constructor_origin,
WebContentsImpl::FromRenderFrameHostID(client_process_id, frame_id) WebContentsImpl::FromRenderFrameHostID(client_process_id, frame_id)
->GetBrowserContext(), ->GetBrowserContext(),
client_process_id, frame_id)) { client_process_id, frame_id)) {
...@@ -130,9 +142,9 @@ void SharedWorkerServiceImpl::ConnectToWorker( ...@@ -130,9 +142,9 @@ void SharedWorkerServiceImpl::ConnectToWorker(
} }
SharedWorkerInstance instance( SharedWorkerInstance instance(
info->url, info->name, render_frame_host->GetLastCommittedOrigin(), info->url, info->name, constructor_origin, info->content_security_policy,
info->content_security_policy, info->content_security_policy_type, info->content_security_policy_type, info->creation_address_space,
info->creation_address_space, creation_context_type); creation_context_type);
SharedWorkerHost* host = FindMatchingSharedWorkerHost( SharedWorkerHost* host = FindMatchingSharedWorkerHost(
instance.url(), instance.name(), instance.constructor_origin()); instance.url(), instance.name(), instance.constructor_origin());
......
...@@ -326,6 +326,11 @@ bool ContentBrowserClient::AllowSharedWorker( ...@@ -326,6 +326,11 @@ bool ContentBrowserClient::AllowSharedWorker(
return true; return true;
} }
bool ContentBrowserClient::DoesSchemeAllowCrossOriginSharedWorker(
const std::string& scheme) {
return false;
}
bool ContentBrowserClient::AllowSignedExchange(BrowserContext* context) { bool ContentBrowserClient::AllowSignedExchange(BrowserContext* context) {
return true; return true;
} }
......
...@@ -578,6 +578,11 @@ class CONTENT_EXPORT ContentBrowserClient { ...@@ -578,6 +578,11 @@ class CONTENT_EXPORT ContentBrowserClient {
int render_process_id, int render_process_id,
int render_frame_id); int render_frame_id);
// Allow the embedder to control if a page/worker with |scheme| URL can create
// a cross-origin shared workers.
virtual bool DoesSchemeAllowCrossOriginSharedWorker(
const std::string& scheme);
// Allows the embedder to control whether Signed HTTP Exchanges (SXG) can be // Allows the embedder to control whether Signed HTTP Exchanges (SXG) can be
// loaded. This is called on the UI thread. // loaded. This is called on the UI thread.
virtual bool AllowSignedExchange(BrowserContext* context); virtual bool AllowSignedExchange(BrowserContext* context);
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <tuple> #include <tuple>
#include "base/logging.h" #include "base/logging.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
namespace content { namespace content {
...@@ -24,7 +26,13 @@ SharedWorkerInstance::SharedWorkerInstance( ...@@ -24,7 +26,13 @@ SharedWorkerInstance::SharedWorkerInstance(
content_security_policy_(content_security_policy), content_security_policy_(content_security_policy),
content_security_policy_type_(security_policy_type), content_security_policy_type_(security_policy_type),
creation_address_space_(creation_address_space), creation_address_space_(creation_address_space),
creation_context_type_(creation_context_type) {} creation_context_type_(creation_context_type) {
// Ensure the same-origin policy is enforced correctly.
DCHECK(url.SchemeIs(url::kDataScheme) ||
GetContentClient()->browser()->DoesSchemeAllowCrossOriginSharedWorker(
constructor_origin.scheme()) ||
url::Origin::Create(url).IsSameOriginWith(constructor_origin));
}
SharedWorkerInstance::SharedWorkerInstance(const SharedWorkerInstance& other) = SharedWorkerInstance::SharedWorkerInstance(const SharedWorkerInstance& other) =
default; default;
...@@ -44,11 +52,6 @@ bool SharedWorkerInstance::Matches( ...@@ -44,11 +52,6 @@ bool SharedWorkerInstance::Matches(
const GURL& url, const GURL& url,
const std::string& name, const std::string& name,
const url::Origin& constructor_origin) const { const url::Origin& constructor_origin) const {
// |url| and |constructor_origin| should be in the same origin, or |url|
// should be a data: URL.
DCHECK(url::Origin::Create(url).IsSameOriginWith(constructor_origin) ||
url.SchemeIs(url::kDataScheme));
// Step 11.2: "If there exists a SharedWorkerGlobalScope object whose closing // Step 11.2: "If there exists a SharedWorkerGlobalScope object whose closing
// flag is false, constructor origin is same origin with outside settings's // flag is false, constructor origin is same origin with outside settings's
// origin, constructor url equals urlRecord, and name equals the value of // origin, constructor url equals urlRecord, and name equals the value of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment