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

Side by Side Diff: extensions/common/permissions/permissions_data.cc

Issue 2499493004: Communicate ExtensionSettings policy to renderers (Closed)
Patch Set: -Forgot to remove comments Created 3 years, 8 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "extensions/common/permissions/permissions_data.h" 5 #include "extensions/common/permissions/permissions_data.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/lazy_instance.h"
11 #include "base/macros.h" 12 #include "base/macros.h"
12 #include "content/public/common/url_constants.h" 13 #include "content/public/common/url_constants.h"
13 #include "extensions/common/constants.h" 14 #include "extensions/common/constants.h"
14 #include "extensions/common/error_utils.h" 15 #include "extensions/common/error_utils.h"
15 #include "extensions/common/extension.h" 16 #include "extensions/common/extension.h"
16 #include "extensions/common/extensions_client.h" 17 #include "extensions/common/extensions_client.h"
17 #include "extensions/common/manifest.h" 18 #include "extensions/common/manifest.h"
18 #include "extensions/common/manifest_constants.h" 19 #include "extensions/common/manifest_constants.h"
19 #include "extensions/common/manifest_handlers/permissions_parser.h" 20 #include "extensions/common/manifest_handlers/permissions_parser.h"
20 #include "extensions/common/permissions/api_permission.h" 21 #include "extensions/common/permissions/api_permission.h"
21 #include "extensions/common/permissions/permission_message_provider.h" 22 #include "extensions/common/permissions/permission_message_provider.h"
22 #include "extensions/common/switches.h" 23 #include "extensions/common/switches.h"
23 #include "extensions/common/url_pattern_set.h" 24 #include "extensions/common/url_pattern_set.h"
24 #include "url/gurl.h" 25 #include "url/gurl.h"
25 #include "url/url_constants.h" 26 #include "url/url_constants.h"
26 27
27 namespace extensions { 28 namespace extensions {
28 29
29 namespace { 30 namespace {
30 31
31 PermissionsData::PolicyDelegate* g_policy_delegate = nullptr; 32 PermissionsData::PolicyDelegate* g_policy_delegate = nullptr;
32 33
34 struct DefaultRuntimePolicy {
35 URLPatternSet blocked_hosts;
36 URLPatternSet allowed_hosts;
37 };
38 // URLs an extension can't interact with. An extension can override these
39 // settings by declaring its own list of blocked and allowed hosts using
40 // policy_blocked_hosts and policy_allowed_hosts.
41 base::LazyInstance<DefaultRuntimePolicy>::Leaky default_runtime_policy =
42 LAZY_INSTANCE_INITIALIZER;
43
33 class AutoLockOnValidThread { 44 class AutoLockOnValidThread {
34 public: 45 public:
35 AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker) 46 AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker)
36 : auto_lock_(lock) { 47 : auto_lock_(lock) {
37 DCHECK(!thread_checker || thread_checker->CalledOnValidThread()); 48 DCHECK(!thread_checker || thread_checker->CalledOnValidThread());
38 } 49 }
39 50
40 private: 51 private:
41 base::AutoLock auto_lock_; 52 base::AutoLock auto_lock_;
42 53
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 bool PermissionsData::ShouldSkipPermissionWarnings( 91 bool PermissionsData::ShouldSkipPermissionWarnings(
81 const std::string& extension_id) { 92 const std::string& extension_id) {
82 // See http://b/4946060 for more details. 93 // See http://b/4946060 for more details.
83 return extension_id == extension_misc::kProdHangoutsExtensionId; 94 return extension_id == extension_misc::kProdHangoutsExtensionId;
84 } 95 }
85 96
86 // static 97 // static
87 bool PermissionsData::IsRestrictedUrl(const GURL& document_url, 98 bool PermissionsData::IsRestrictedUrl(const GURL& document_url,
88 const Extension* extension, 99 const Extension* extension,
89 std::string* error) { 100 std::string* error) {
101 if (extension &&
102 extension->permissions_data()->IsRuntimeBlockedHost(document_url)) {
103 *error = manifest_errors::kCannotAccessPage;
104 return true;
105 }
90 if (extension && CanExecuteScriptEverywhere(extension)) 106 if (extension && CanExecuteScriptEverywhere(extension))
91 return false; 107 return false;
92 108
93 // Check if the scheme is valid for extensions. If not, return. 109 // Check if the scheme is valid for extensions. If not, return.
94 if (!URLPattern::IsValidSchemeForExtensions(document_url.scheme()) && 110 if (!URLPattern::IsValidSchemeForExtensions(document_url.scheme()) &&
95 document_url.spec() != url::kAboutBlankURL) { 111 document_url.spec() != url::kAboutBlankURL) {
96 if (error) { 112 if (error) {
97 if (extension->permissions_data()->active_permissions().HasAPIPermission( 113 if (extension->permissions_data()->active_permissions().HasAPIPermission(
98 APIPermission::kTab)) { 114 APIPermission::kTab)) {
99 *error = ErrorUtils::FormatErrorMessage( 115 *error = ErrorUtils::FormatErrorMessage(
(...skipping 20 matching lines...) Expand all
120 if (extension && document_url.SchemeIs(kExtensionScheme) && 136 if (extension && document_url.SchemeIs(kExtensionScheme) &&
121 document_url.host() != extension->id() && !allow_on_chrome_urls) { 137 document_url.host() != extension->id() && !allow_on_chrome_urls) {
122 if (error) 138 if (error)
123 *error = manifest_errors::kCannotAccessExtensionUrl; 139 *error = manifest_errors::kCannotAccessExtensionUrl;
124 return true; 140 return true;
125 } 141 }
126 142
127 return false; 143 return false;
128 } 144 }
129 145
146 bool PermissionsData::UsesDefaultPolicyHostRestrictions() const {
147 DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread());
148 return uses_default_policy_host_restrictions;
149 }
150
151 const URLPatternSet& PermissionsData::default_policy_blocked_hosts() {
152 return default_runtime_policy.Get().blocked_hosts;
153 }
154
155 const URLPatternSet& PermissionsData::default_policy_allowed_hosts() {
156 return default_runtime_policy.Get().allowed_hosts;
157 }
158
159 const URLPatternSet& PermissionsData::policy_blocked_hosts() const {
160 DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread());
161 if (uses_default_policy_host_restrictions)
162 return default_policy_blocked_hosts();
163 return policy_blocked_hosts_unsafe_;
164 }
165
166 const URLPatternSet& PermissionsData::policy_allowed_hosts() const {
167 DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread());
168 if (uses_default_policy_host_restrictions)
169 return default_policy_allowed_hosts();
170 return policy_allowed_hosts_unsafe_;
171 }
172
130 void PermissionsData::BindToCurrentThread() const { 173 void PermissionsData::BindToCurrentThread() const {
131 DCHECK(!thread_checker_); 174 DCHECK(!thread_checker_);
132 thread_checker_.reset(new base::ThreadChecker()); 175 thread_checker_.reset(new base::ThreadChecker());
133 } 176 }
134 177
135 void PermissionsData::SetPermissions( 178 void PermissionsData::SetPermissions(
136 std::unique_ptr<const PermissionSet> active, 179 std::unique_ptr<const PermissionSet> active,
137 std::unique_ptr<const PermissionSet> withheld) const { 180 std::unique_ptr<const PermissionSet> withheld) const {
138 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); 181 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
139 active_permissions_unsafe_ = std::move(active); 182 active_permissions_unsafe_ = std::move(active);
140 withheld_permissions_unsafe_ = std::move(withheld); 183 withheld_permissions_unsafe_ = std::move(withheld);
141 } 184 }
142 185
186 void PermissionsData::SetPolicyHostRestrictions(
187 const URLPatternSet& runtime_blocked_hosts,
188 const URLPatternSet& runtime_allowed_hosts) const {
189 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
190 policy_blocked_hosts_unsafe_ = runtime_blocked_hosts;
dcheng 2017/03/31 23:48:06 I'm having trouble understanding why it's sometime
nrpeter 2017/04/01 00:19:02 Good point, added the check to SetUsesDefaultHostR
dcheng 2017/04/01 00:24:07 I don't really know, but my question is more about
nrpeter 2017/04/03 22:35:48 I was copying active_permissions() from permission
Devlin 2017/04/04 16:29:10 It's only safe to grab them directly (using the *u
nrpeter 2017/04/05 23:13:26 FYI: We are acquiring the lock in SetUsesDefaultHo
dcheng 2017/04/07 06:57:19 Can we use runtime_lock_.AssertAquired() to make t
nrpeter 2017/04/12 23:35:44 Added the lock assertion check as requested.
191 policy_allowed_hosts_unsafe_ = runtime_allowed_hosts;
192 }
193
194 void PermissionsData::SetUsesDefaultHostRestrictions(
195 bool uses_default_restrictions) const {
196 uses_default_policy_host_restrictions = uses_default_restrictions;
197 }
198
199 // static
200 void PermissionsData::SetDefaultPolicyHostRestrictions(
201 const URLPatternSet& default_runtime_blocked_hosts,
202 const URLPatternSet& default_runtime_allowed_hosts) {
203 default_runtime_policy.Get().blocked_hosts = default_runtime_blocked_hosts;
204 default_runtime_policy.Get().allowed_hosts = default_runtime_allowed_hosts;
205 }
206
143 void PermissionsData::SetActivePermissions( 207 void PermissionsData::SetActivePermissions(
144 std::unique_ptr<const PermissionSet> active) const { 208 std::unique_ptr<const PermissionSet> active) const {
145 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); 209 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
146 active_permissions_unsafe_ = std::move(active); 210 active_permissions_unsafe_ = std::move(active);
147 } 211 }
148 212
149 void PermissionsData::UpdateTabSpecificPermissions( 213 void PermissionsData::UpdateTabSpecificPermissions(
150 int tab_id, 214 int tab_id,
151 const PermissionSet& permissions) const { 215 const PermissionSet& permissions) const {
152 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); 216 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { 265 URLPatternSet PermissionsData::GetEffectiveHostPermissions() const {
202 base::AutoLock auto_lock(runtime_lock_); 266 base::AutoLock auto_lock(runtime_lock_);
203 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts(); 267 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts();
204 for (const auto& val : tab_specific_permissions_) 268 for (const auto& val : tab_specific_permissions_)
205 effective_hosts.AddPatterns(val.second->effective_hosts()); 269 effective_hosts.AddPatterns(val.second->effective_hosts());
206 return effective_hosts; 270 return effective_hosts;
207 } 271 }
208 272
209 bool PermissionsData::HasHostPermission(const GURL& url) const { 273 bool PermissionsData::HasHostPermission(const GURL& url) const {
210 base::AutoLock auto_lock(runtime_lock_); 274 base::AutoLock auto_lock(runtime_lock_);
211 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url); 275 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url) &&
276 !IsRuntimeBlockedHost(url);
212 } 277 }
213 278
214 bool PermissionsData::HasEffectiveAccessToAllHosts() const { 279 bool PermissionsData::HasEffectiveAccessToAllHosts() const {
215 base::AutoLock auto_lock(runtime_lock_); 280 base::AutoLock auto_lock(runtime_lock_);
216 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); 281 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts();
217 } 282 }
218 283
219 PermissionMessages PermissionsData::GetPermissionMessages() const { 284 PermissionMessages PermissionsData::GetPermissionMessages() const {
220 base::AutoLock auto_lock(runtime_lock_); 285 base::AutoLock auto_lock(runtime_lock_);
221 return PermissionMessageProvider::Get()->GetPermissionMessages( 286 return PermissionMessageProvider::Get()->GetPermissionMessages(
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 if (tab_id >= 0) { 385 if (tab_id >= 0) {
321 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); 386 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id);
322 if (tab_permissions && 387 if (tab_permissions &&
323 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { 388 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) {
324 return true; 389 return true;
325 } 390 }
326 } 391 }
327 return false; 392 return false;
328 } 393 }
329 394
395 bool PermissionsData::IsRuntimeBlockedHost(const GURL& url) const {
396 return policy_blocked_hosts().MatchesURL(url) &&
397 !policy_allowed_hosts().MatchesURL(url);
398 }
399
330 PermissionsData::AccessType PermissionsData::CanRunOnPage( 400 PermissionsData::AccessType PermissionsData::CanRunOnPage(
331 const Extension* extension, 401 const Extension* extension,
332 const GURL& document_url, 402 const GURL& document_url,
333 int tab_id, 403 int tab_id,
334 const URLPatternSet& permitted_url_patterns, 404 const URLPatternSet& permitted_url_patterns,
335 const URLPatternSet& withheld_url_patterns, 405 const URLPatternSet& withheld_url_patterns,
336 std::string* error) const { 406 std::string* error) const {
337 runtime_lock_.AssertAcquired(); 407 runtime_lock_.AssertAcquired();
338 if (g_policy_delegate && 408 if (g_policy_delegate &&
339 !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url, 409 !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url,
340 tab_id, error)) { 410 tab_id, error))
411 return ACCESS_DENIED;
412
413 if (IsRuntimeBlockedHost(document_url)) {
414 if (error)
415 *error =
416 "This page cannot be scripted due to an ExtensionsSettings policy.";
341 return ACCESS_DENIED; 417 return ACCESS_DENIED;
342 } 418 }
343 419
344 if (IsRestrictedUrl(document_url, extension, error)) 420 if (IsRestrictedUrl(document_url, extension, error))
345 return ACCESS_DENIED; 421 return ACCESS_DENIED;
346 422
347 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url)) 423 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url))
348 return ACCESS_ALLOWED; 424 return ACCESS_ALLOWED;
349 425
350 if (permitted_url_patterns.MatchesURL(document_url)) 426 if (permitted_url_patterns.MatchesURL(document_url))
351 return ACCESS_ALLOWED; 427 return ACCESS_ALLOWED;
352 428
353 if (withheld_url_patterns.MatchesURL(document_url)) 429 if (withheld_url_patterns.MatchesURL(document_url))
354 return ACCESS_WITHHELD; 430 return ACCESS_WITHHELD;
355 431
356 if (error) { 432 if (error) {
357 if (extension->permissions_data()->active_permissions().HasAPIPermission( 433 if (extension->permissions_data()->active_permissions().HasAPIPermission(
358 APIPermission::kTab)) { 434 APIPermission::kTab)) {
359 *error = ErrorUtils::FormatErrorMessage( 435 *error = ErrorUtils::FormatErrorMessage(
360 manifest_errors::kCannotAccessPageWithUrl, document_url.spec()); 436 manifest_errors::kCannotAccessPageWithUrl, document_url.spec());
361 } else { 437 } else {
362 *error = manifest_errors::kCannotAccessPage; 438 *error = manifest_errors::kCannotAccessPage;
363 } 439 }
364 } 440 }
365 441
366 return ACCESS_DENIED; 442 return ACCESS_DENIED;
367 } 443 }
368 444
369 } // namespace extensions 445 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698