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 a06b79698b9b021976ef7651680090a6322b47fe..5666813816483ae5913a8e6db8b90d8d558e06c9 100644 |
--- a/content/browser/service_worker/service_worker_provider_host.cc |
+++ b/content/browser/service_worker/service_worker_provider_host.cc |
@@ -22,8 +22,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 { |
@@ -55,7 +58,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( |
@@ -63,6 +67,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()), |
@@ -71,6 +76,7 @@ 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) { |
@@ -112,6 +118,20 @@ int ServiceWorkerProviderHost::frame_id() const { |
return MSG_ROUTING_NONE; |
} |
+bool ServiceWorkerProviderHost::IsContextSecureForServiceWorker() const { |
+ DCHECK(document_url_.is_valid()); |
+ 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 +186,7 @@ void ServiceWorkerProviderHost::SetTopmostFrameUrl(const GURL& url) { |
void ServiceWorkerProviderHost::SetControllerVersionAttribute( |
ServiceWorkerVersion* version, |
bool notify_controllerchange) { |
+ CHECK(!version || IsContextSecureForServiceWorker()); |
if (version == controlling_version_.get()) |
return; |
@@ -239,6 +260,7 @@ blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type() |
void ServiceWorkerProviderHost::AssociateRegistration( |
ServiceWorkerRegistration* registration, |
bool notify_controllerchange) { |
+ CHECK(IsContextSecureForServiceWorker()); |
DCHECK(CanAssociateRegistration(registration)); |
associated_registration_ = registration; |
AddMatchingRegistration(registration); |
@@ -267,6 +289,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; |