Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1260)

Side by Side Diff: content/child/service_worker/service_worker_network_provider.cc

Issue 2142523004: M52: Merge "Reland: service worker: Don't control a subframe of an insecure context" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2743
Patch Set: fix compile errors Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/child/service_worker/service_worker_network_provider.h" 5 #include "content/child/service_worker/service_worker_network_provider.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "content/child/child_thread_impl.h" 8 #include "content/child/child_thread_impl.h"
9 #include "content/child/service_worker/service_worker_provider_context.h" 9 #include "content/child/service_worker/service_worker_provider_context.h"
10 #include "content/common/navigation_params.h" 10 #include "content/common/navigation_params.h"
11 #include "content/common/service_worker/service_worker_messages.h" 11 #include "content/common/service_worker/service_worker_messages.h"
12 #include "content/common/service_worker/service_worker_utils.h" 12 #include "content/common/service_worker/service_worker_utils.h"
13 #include "content/public/common/browser_side_navigation_policy.h" 13 #include "content/public/common/browser_side_navigation_policy.h"
14 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
15 #include "third_party/WebKit/public/web/WebLocalFrame.h"
16 #include "third_party/WebKit/public/web/WebSandboxFlags.h"
14 17
15 namespace content { 18 namespace content {
16 19
17 namespace { 20 namespace {
18 21
19 const char kUserDataKey[] = "SWProviderKey"; 22 const char kUserDataKey[] = "SWProviderKey";
20 23
21 // Must be unique in the child process. 24 // Must be unique in the child process.
22 int GetNextProviderId() { 25 int GetNextProviderId() {
23 static base::StaticAtomicSequenceNumber sequence; 26 static base::StaticAtomicSequenceNumber sequence;
24 return sequence.GetNext(); // We start at zero. 27 return sequence.GetNext(); // We start at zero.
25 } 28 }
26 29
27 // When the provider is for a sandboxed iframe we use 30 // Returns whether it's possible for a document whose frame is a descendant of
28 // kInvalidServiceWorkerProviderId as the provider type and we don't create 31 // |frame| to be a secure context, not considering scheme exceptions (since any
29 // ServiceWorkerProviderContext and ServiceWorkerProviderHost. 32 // document can be a secure context if it has a scheme exception). See
30 int GenerateProviderIdForType(const ServiceWorkerProviderType provider_type) { 33 // Document::isSecureContextImpl for more details.
31 if (provider_type == SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME) 34 bool IsFrameSecure(blink::WebFrame* frame) {
32 return kInvalidServiceWorkerProviderId; 35 while (frame) {
33 return GetNextProviderId(); 36 if (!frame->getSecurityOrigin().isPotentiallyTrustworthy())
37 return false;
38 frame = frame->parent();
39 }
40 return true;
34 } 41 }
35 42
36 } // namespace 43 } // namespace
37 44
38 void ServiceWorkerNetworkProvider::AttachToDocumentState( 45 void ServiceWorkerNetworkProvider::AttachToDocumentState(
39 base::SupportsUserData* datasource_userdata, 46 base::SupportsUserData* datasource_userdata,
40 std::unique_ptr<ServiceWorkerNetworkProvider> network_provider) { 47 std::unique_ptr<ServiceWorkerNetworkProvider> network_provider) {
41 datasource_userdata->SetUserData(&kUserDataKey, network_provider.release()); 48 datasource_userdata->SetUserData(&kUserDataKey, network_provider.release());
42 } 49 }
43 50
44 ServiceWorkerNetworkProvider* ServiceWorkerNetworkProvider::FromDocumentState( 51 ServiceWorkerNetworkProvider* ServiceWorkerNetworkProvider::FromDocumentState(
45 base::SupportsUserData* datasource_userdata) { 52 base::SupportsUserData* datasource_userdata) {
46 return static_cast<ServiceWorkerNetworkProvider*>( 53 return static_cast<ServiceWorkerNetworkProvider*>(
47 datasource_userdata->GetUserData(&kUserDataKey)); 54 datasource_userdata->GetUserData(&kUserDataKey));
48 } 55 }
49 56
50 // static 57 // static
51 std::unique_ptr<ServiceWorkerNetworkProvider> 58 std::unique_ptr<ServiceWorkerNetworkProvider>
52 ServiceWorkerNetworkProvider::CreateForNavigation( 59 ServiceWorkerNetworkProvider::CreateForNavigation(
53 int route_id, 60 int route_id,
54 const RequestNavigationParams& request_params, 61 const RequestNavigationParams& request_params,
55 blink::WebSandboxFlags sandbox_flags, 62 blink::WebLocalFrame* frame,
56 bool content_initiated) { 63 bool content_initiated) {
57 bool browser_side_navigation = IsBrowserSideNavigationEnabled(); 64 bool browser_side_navigation = IsBrowserSideNavigationEnabled();
58 bool should_create_provider_for_window = false; 65 bool should_create_provider_for_window = false;
59 int service_worker_provider_id = kInvalidServiceWorkerProviderId; 66 int service_worker_provider_id = kInvalidServiceWorkerProviderId;
60 std::unique_ptr<ServiceWorkerNetworkProvider> network_provider; 67 std::unique_ptr<ServiceWorkerNetworkProvider> network_provider;
61 68
62 // Determine if a ServiceWorkerNetworkProvider should be created and properly 69 // Determine if a ServiceWorkerNetworkProvider should be created and properly
63 // initialized for the navigation. A default ServiceWorkerNetworkProvider 70 // initialized for the navigation. A default ServiceWorkerNetworkProvider
64 // will always be created since it is expected in a certain number of places, 71 // will always be created since it is expected in a certain number of places,
65 // however it will have an invalid id. 72 // however it will have an invalid id.
66 // PlzNavigate: |service_worker_provider_id| can be sent by the browser, if 73 // PlzNavigate: |service_worker_provider_id| can be sent by the browser, if
67 // it already created the SeviceWorkerProviderHost. 74 // it already created the SeviceWorkerProviderHost.
68 if (browser_side_navigation && !content_initiated) { 75 if (browser_side_navigation && !content_initiated) {
69 should_create_provider_for_window = 76 should_create_provider_for_window =
70 request_params.should_create_service_worker; 77 request_params.should_create_service_worker;
71 service_worker_provider_id = request_params.service_worker_provider_id; 78 service_worker_provider_id = request_params.service_worker_provider_id;
72 DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId( 79 DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId(
73 service_worker_provider_id) || 80 service_worker_provider_id) ||
74 service_worker_provider_id == kInvalidServiceWorkerProviderId); 81 service_worker_provider_id == kInvalidServiceWorkerProviderId);
75 } else { 82 } else {
76 should_create_provider_for_window = 83 should_create_provider_for_window =
77 (sandbox_flags & blink::WebSandboxFlags::Origin) != 84 ((frame->effectiveSandboxFlags() & blink::WebSandboxFlags::Origin) !=
78 blink::WebSandboxFlags::Origin; 85 blink::WebSandboxFlags::Origin);
79 } 86 }
80 87
81 // Now create the ServiceWorkerNetworkProvider (with invalid id if needed). 88 // Now create the ServiceWorkerNetworkProvider (with invalid id if needed).
82 if (should_create_provider_for_window) { 89 if (should_create_provider_for_window) {
90 // Ideally Document::isSecureContext would be called here, but the document
91 // is not created yet, and due to redirects the URL may change. So pass
92 // is_parent_frame_secure to the browser process, so it can determine the
93 // context security when deciding whether to allow a service worker to
94 // control the document.
95 const bool is_parent_frame_secure = IsFrameSecure(frame->parent());
96
83 if (service_worker_provider_id == kInvalidServiceWorkerProviderId) { 97 if (service_worker_provider_id == kInvalidServiceWorkerProviderId) {
84 network_provider = std::unique_ptr<ServiceWorkerNetworkProvider>( 98 network_provider = std::unique_ptr<ServiceWorkerNetworkProvider>(
85 new ServiceWorkerNetworkProvider(route_id, 99 new ServiceWorkerNetworkProvider(route_id,
86 SERVICE_WORKER_PROVIDER_FOR_WINDOW)); 100 SERVICE_WORKER_PROVIDER_FOR_WINDOW,
101 is_parent_frame_secure));
87 } else { 102 } else {
88 CHECK(browser_side_navigation); 103 CHECK(browser_side_navigation);
89 DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId( 104 DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId(
90 service_worker_provider_id)); 105 service_worker_provider_id));
91 network_provider = std::unique_ptr<ServiceWorkerNetworkProvider>( 106 network_provider = std::unique_ptr<ServiceWorkerNetworkProvider>(
92 new ServiceWorkerNetworkProvider(route_id, 107 new ServiceWorkerNetworkProvider(
93 SERVICE_WORKER_PROVIDER_FOR_WINDOW, 108 route_id, SERVICE_WORKER_PROVIDER_FOR_WINDOW,
94 service_worker_provider_id)); 109 service_worker_provider_id, is_parent_frame_secure));
95 } 110 }
96 } else { 111 } else {
97 network_provider = std::unique_ptr<ServiceWorkerNetworkProvider>( 112 network_provider = std::unique_ptr<ServiceWorkerNetworkProvider>(
98 new ServiceWorkerNetworkProvider()); 113 new ServiceWorkerNetworkProvider());
99 } 114 }
100 return network_provider; 115 return network_provider;
101 } 116 }
102 117
103 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider( 118 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
104 int route_id, 119 int route_id,
105 ServiceWorkerProviderType provider_type, 120 ServiceWorkerProviderType provider_type,
106 int browser_provider_id) 121 int browser_provider_id,
122 bool is_parent_frame_secure)
107 : provider_id_(browser_provider_id) { 123 : provider_id_(browser_provider_id) {
108 if (provider_id_ == kInvalidServiceWorkerProviderId) 124 if (provider_id_ == kInvalidServiceWorkerProviderId)
109 return; 125 return;
110 if (!ChildThreadImpl::current()) 126 if (!ChildThreadImpl::current())
111 return; // May be null in some tests. 127 return; // May be null in some tests.
112 context_ = new ServiceWorkerProviderContext( 128 context_ = new ServiceWorkerProviderContext(
113 provider_id_, provider_type, 129 provider_id_, provider_type,
114 ChildThreadImpl::current()->thread_safe_sender()); 130 ChildThreadImpl::current()->thread_safe_sender());
115 ChildThreadImpl::current()->Send(new ServiceWorkerHostMsg_ProviderCreated( 131 ChildThreadImpl::current()->Send(new ServiceWorkerHostMsg_ProviderCreated(
116 provider_id_, route_id, provider_type)); 132 provider_id_, route_id, provider_type, is_parent_frame_secure));
117 } 133 }
118 134
119 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider( 135 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
120 int route_id, 136 int route_id,
121 ServiceWorkerProviderType provider_type) 137 ServiceWorkerProviderType provider_type,
138 bool is_parent_frame_secure)
122 : ServiceWorkerNetworkProvider(route_id, 139 : ServiceWorkerNetworkProvider(route_id,
123 provider_type, 140 provider_type,
124 GenerateProviderIdForType(provider_type)) {} 141 GetNextProviderId(),
142 is_parent_frame_secure) {}
125 143
126 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider() 144 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider()
127 : provider_id_(kInvalidServiceWorkerProviderId) {} 145 : provider_id_(kInvalidServiceWorkerProviderId) {}
128 146
129 ServiceWorkerNetworkProvider::~ServiceWorkerNetworkProvider() { 147 ServiceWorkerNetworkProvider::~ServiceWorkerNetworkProvider() {
130 if (provider_id_ == kInvalidServiceWorkerProviderId) 148 if (provider_id_ == kInvalidServiceWorkerProviderId)
131 return; 149 return;
132 if (!ChildThreadImpl::current()) 150 if (!ChildThreadImpl::current())
133 return; // May be null in some tests. 151 return; // May be null in some tests.
134 ChildThreadImpl::current()->Send( 152 ChildThreadImpl::current()->Send(
135 new ServiceWorkerHostMsg_ProviderDestroyed(provider_id_)); 153 new ServiceWorkerHostMsg_ProviderDestroyed(provider_id_));
136 } 154 }
137 155
138 void ServiceWorkerNetworkProvider::SetServiceWorkerVersionId( 156 void ServiceWorkerNetworkProvider::SetServiceWorkerVersionId(
139 int64_t version_id) { 157 int64_t version_id) {
140 DCHECK_NE(kInvalidServiceWorkerProviderId, provider_id_); 158 DCHECK_NE(kInvalidServiceWorkerProviderId, provider_id_);
141 if (!ChildThreadImpl::current()) 159 if (!ChildThreadImpl::current())
142 return; // May be null in some tests. 160 return; // May be null in some tests.
143 ChildThreadImpl::current()->Send( 161 ChildThreadImpl::current()->Send(
144 new ServiceWorkerHostMsg_SetVersionId(provider_id_, version_id)); 162 new ServiceWorkerHostMsg_SetVersionId(provider_id_, version_id));
145 } 163 }
146 164
147 bool ServiceWorkerNetworkProvider::IsControlledByServiceWorker() const { 165 bool ServiceWorkerNetworkProvider::IsControlledByServiceWorker() const {
148 return context() && context()->controller(); 166 return context() && context()->controller();
149 } 167 }
150 168
151 } // namespace content 169 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698