Index: content/browser/service_worker/service_worker_provider_host.cc |
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc |
index b02d789b9c612edd6b6ae041d13a2440a6dfa9db..2666b5dd19137d70eecbc204e79509e9b0c09645 100644 |
--- a/content/browser/service_worker/service_worker_provider_host.cc |
+++ b/content/browser/service_worker/service_worker_provider_host.cc |
@@ -21,8 +21,11 @@ |
#include "content/common/service_worker/service_worker_messages.h" |
#include "content/common/service_worker/service_worker_types.h" |
#include "content/common/service_worker/service_worker_utils.h" |
+#include "content/public/browser/content_browser_client.h" |
#include "content/public/common/browser_side_navigation_policy.h" |
#include "content/public/common/child_process_host.h" |
+#include "content/public/common/content_client.h" |
+#include "content/public/common/origin_util.h" |
namespace content { |
@@ -54,7 +57,8 @@ ServiceWorkerProviderHost::PreCreateNavigationHost( |
return std::unique_ptr<ServiceWorkerProviderHost>( |
new ServiceWorkerProviderHost( |
ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE, provider_id, |
- SERVICE_WORKER_PROVIDER_FOR_WINDOW, context, nullptr)); |
+ SERVICE_WORKER_PROVIDER_FOR_WINDOW, FrameSecurityLevel::UNINITIALIZED, |
+ context, nullptr)); |
} |
ServiceWorkerProviderHost::ServiceWorkerProviderHost( |
@@ -62,6 +66,7 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost( |
int route_id, |
int provider_id, |
ServiceWorkerProviderType provider_type, |
+ FrameSecurityLevel parent_frame_security_level, |
base::WeakPtr<ServiceWorkerContextCore> context, |
ServiceWorkerDispatcherHost* dispatcher_host) |
: client_uuid_(base::GenerateGUID()), |
@@ -70,11 +75,11 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost( |
render_thread_id_(kDocumentMainThreadId), |
provider_id_(provider_id), |
provider_type_(provider_type), |
+ parent_frame_security_level_(parent_frame_security_level), |
context_(context), |
dispatcher_host_(dispatcher_host), |
allow_association_(true) { |
DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_type_); |
- DCHECK_NE(SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME, provider_type_); |
// PlzNavigate |
CHECK(render_process_id != ChildProcessHost::kInvalidUniqueID || |
@@ -112,6 +117,25 @@ int ServiceWorkerProviderHost::frame_id() const { |
return MSG_ROUTING_NONE; |
} |
+bool ServiceWorkerProviderHost::IsContextSecureForServiceWorker() const { |
+ // |document_url_| may be empty if loading has not begun, or |
+ // ServiceWorkerRequestHandler didn't handle the load (because e.g. another |
+ // handler did first, or the initial request URL was such that |
+ // OriginCanAccessServiceWorkers returned false). |
+ if (!document_url_.is_valid()) |
+ return false; |
+ if (!OriginCanAccessServiceWorkers(document_url_)) |
+ return false; |
+ |
+ if (is_parent_frame_secure()) |
+ return true; |
+ |
+ std::set<std::string> schemes; |
+ GetContentClient()->browser()->GetSchemesBypassingSecureContextCheckWhitelist( |
+ &schemes); |
+ return schemes.find(document_url().scheme()) != schemes.end(); |
+} |
+ |
void ServiceWorkerProviderHost::OnVersionAttributesChanged( |
ServiceWorkerRegistration* registration, |
ChangedVersionAttributesMask changed_mask, |
@@ -166,6 +190,7 @@ void ServiceWorkerProviderHost::SetTopmostFrameUrl(const GURL& url) { |
void ServiceWorkerProviderHost::SetControllerVersionAttribute( |
ServiceWorkerVersion* version, |
bool notify_controllerchange) { |
+ CHECK(!version || IsContextSecureForServiceWorker()); |
if (version == controlling_version_.get()) |
return; |
@@ -212,7 +237,6 @@ bool ServiceWorkerProviderHost::IsProviderForClient() const { |
return true; |
case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: |
return false; |
- case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME: |
case SERVICE_WORKER_PROVIDER_UNKNOWN: |
NOTREACHED() << provider_type_; |
} |
@@ -230,7 +254,6 @@ blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type() |
case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: |
return blink::WebServiceWorkerClientTypeSharedWorker; |
case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: |
- case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME: |
case SERVICE_WORKER_PROVIDER_UNKNOWN: |
NOTREACHED() << provider_type_; |
} |
@@ -241,6 +264,7 @@ blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type() |
void ServiceWorkerProviderHost::AssociateRegistration( |
ServiceWorkerRegistration* registration, |
bool notify_controllerchange) { |
+ CHECK(IsContextSecureForServiceWorker()); |
DCHECK(CanAssociateRegistration(registration)); |
associated_registration_ = registration; |
AddMatchingRegistration(registration); |
@@ -269,6 +293,8 @@ void ServiceWorkerProviderHost::AddMatchingRegistration( |
ServiceWorkerRegistration* registration) { |
DCHECK(ServiceWorkerUtils::ScopeMatches( |
registration->pattern(), document_url_)); |
+ if (!IsContextSecureForServiceWorker()) |
+ return; |
size_t key = registration->pattern().spec().size(); |
if (ContainsKey(matching_registrations_, key)) |
return; |