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

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

Issue 2499493004: Communicate ExtensionSettings policy to renderers (Closed)
Patch Set: Style fixes, prevent heap leak. Created 3 years, 10 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"
(...skipping 11 matching lines...) Expand all
22 #include "extensions/common/switches.h" 22 #include "extensions/common/switches.h"
23 #include "extensions/common/url_pattern_set.h" 23 #include "extensions/common/url_pattern_set.h"
24 #include "url/gurl.h" 24 #include "url/gurl.h"
25 #include "url/url_constants.h" 25 #include "url/url_constants.h"
26 26
27 namespace extensions { 27 namespace extensions {
28 28
29 namespace { 29 namespace {
30 30
31 PermissionsData::PolicyDelegate* g_policy_delegate = nullptr; 31 PermissionsData::PolicyDelegate* g_policy_delegate = nullptr;
32 // URLs an extension can't interact with. Overridden by
33 // runtime_blocked_hosts of an individual extension's PermissionsData.
34 URLPatternSet* default_runtime_blocked_hosts_unsafe_ = nullptr;
Devlin 2017/02/14 23:17:10 I think I'd prefer these to be stored in a struct
Devlin 2017/02/14 23:17:10 the trailing _ is used for member variables; this
nrpeter 2017/03/22 23:47:39 Done.
nrpeter 2017/03/22 23:47:39 Done.
35 // URLs an extension can interact with regardless of
36 // default_runtime_blocked_hosts_unsafe. Overridden by
37 // runtime_allowed_hosts of an individual extension's PermissionsData.
38 URLPatternSet* default_runtime_allowed_hosts_unsafe_ = nullptr;
32 39
33 class AutoLockOnValidThread { 40 class AutoLockOnValidThread {
34 public: 41 public:
35 AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker) 42 AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker)
36 : auto_lock_(lock) { 43 : auto_lock_(lock) {
37 DCHECK(!thread_checker || thread_checker->CalledOnValidThread()); 44 DCHECK(!thread_checker || thread_checker->CalledOnValidThread());
38 } 45 }
39 46
40 private: 47 private:
41 base::AutoLock auto_lock_; 48 base::AutoLock auto_lock_;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 bool PermissionsData::ShouldSkipPermissionWarnings( 87 bool PermissionsData::ShouldSkipPermissionWarnings(
81 const std::string& extension_id) { 88 const std::string& extension_id) {
82 // See http://b/4946060 for more details. 89 // See http://b/4946060 for more details.
83 return extension_id == extension_misc::kProdHangoutsExtensionId; 90 return extension_id == extension_misc::kProdHangoutsExtensionId;
84 } 91 }
85 92
86 // static 93 // static
87 bool PermissionsData::IsRestrictedUrl(const GURL& document_url, 94 bool PermissionsData::IsRestrictedUrl(const GURL& document_url,
88 const Extension* extension, 95 const Extension* extension,
89 std::string* error) { 96 std::string* error) {
97 if (extension &&
98 extension->permissions_data()->IsRuntimeBlockedHost(document_url)) {
99 *error = manifest_errors::kCannotAccessPage;
100 return true;
101 }
90 if (extension && CanExecuteScriptEverywhere(extension)) 102 if (extension && CanExecuteScriptEverywhere(extension))
91 return false; 103 return false;
92 104
93 // Check if the scheme is valid for extensions. If not, return. 105 // Check if the scheme is valid for extensions. If not, return.
94 if (!URLPattern::IsValidSchemeForExtensions(document_url.scheme()) && 106 if (!URLPattern::IsValidSchemeForExtensions(document_url.scheme()) &&
95 document_url.spec() != url::kAboutBlankURL) { 107 document_url.spec() != url::kAboutBlankURL) {
96 if (error) { 108 if (error) {
97 if (extension->permissions_data()->active_permissions().HasAPIPermission( 109 if (extension->permissions_data()->active_permissions().HasAPIPermission(
98 APIPermission::kTab)) { 110 APIPermission::kTab)) {
99 *error = ErrorUtils::FormatErrorMessage( 111 *error = ErrorUtils::FormatErrorMessage(
(...skipping 20 matching lines...) Expand all
120 if (extension && document_url.SchemeIs(kExtensionScheme) && 132 if (extension && document_url.SchemeIs(kExtensionScheme) &&
121 document_url.host() != extension->id() && !allow_on_chrome_urls) { 133 document_url.host() != extension->id() && !allow_on_chrome_urls) {
122 if (error) 134 if (error)
123 *error = manifest_errors::kCannotAccessExtensionUrl; 135 *error = manifest_errors::kCannotAccessExtensionUrl;
124 return true; 136 return true;
125 } 137 }
126 138
127 return false; 139 return false;
128 } 140 }
129 141
142 bool PermissionsData::UsesDefaultPolicyHostRestrictions() const {
143 DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread());
144 return uses_default_policy_host_restrictions_;
145 }
146
147 const URLPatternSet& PermissionsData::default_runtime_blocked_hosts() {
148 if (!default_runtime_blocked_hosts_unsafe_)
149 default_runtime_blocked_hosts_unsafe_ = new URLPatternSet();
150 return *default_runtime_blocked_hosts_unsafe_;
151 }
152
153 const URLPatternSet& PermissionsData::default_runtime_allowed_hosts() {
154 if (!default_runtime_allowed_hosts_unsafe_)
155 default_runtime_allowed_hosts_unsafe_ = new URLPatternSet();
156 return *default_runtime_allowed_hosts_unsafe_;
157 }
158
159 const URLPatternSet& PermissionsData::runtime_blocked_hosts() const {
Devlin 2017/02/14 23:17:10 We should check thread access here.
nrpeter 2017/03/22 23:47:39 Done.
160 if (uses_default_policy_host_restrictions_)
161 return default_runtime_blocked_hosts();
162 return runtime_blocked_hosts_unsafe_;
163 }
164
165 const URLPatternSet& PermissionsData::runtime_allowed_hosts() const {
166 if (uses_default_policy_host_restrictions_)
167 return default_runtime_allowed_hosts();
168 return runtime_allowed_hosts_unsafe_;
169 }
170
130 void PermissionsData::BindToCurrentThread() const { 171 void PermissionsData::BindToCurrentThread() const {
131 DCHECK(!thread_checker_); 172 DCHECK(!thread_checker_);
132 thread_checker_.reset(new base::ThreadChecker()); 173 thread_checker_.reset(new base::ThreadChecker());
133 } 174 }
134 175
135 void PermissionsData::SetPermissions( 176 void PermissionsData::SetPermissions(
136 std::unique_ptr<const PermissionSet> active, 177 std::unique_ptr<const PermissionSet> active,
137 std::unique_ptr<const PermissionSet> withheld) const { 178 std::unique_ptr<const PermissionSet> withheld) const {
138 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); 179 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
139 active_permissions_unsafe_ = std::move(active); 180 active_permissions_unsafe_ = std::move(active);
140 withheld_permissions_unsafe_ = std::move(withheld); 181 withheld_permissions_unsafe_ = std::move(withheld);
141 } 182 }
142 183
184 void PermissionsData::SetPolicyHostRestrictions(
185 const URLPatternSet& runtime_blocked_hosts,
186 const URLPatternSet& runtime_allowed_hosts,
187 const bool uses_default_policy_host_restrictions) const {
188 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
189 runtime_blocked_hosts_unsafe_ = runtime_blocked_hosts;
190 runtime_allowed_hosts_unsafe_ = runtime_allowed_hosts;
191 uses_default_policy_host_restrictions_ =
192 uses_default_policy_host_restrictions;
193 }
194
195 // static
196 void PermissionsData::SetDefaultPolicyHostRestrictions(
197 const URLPatternSet& default_runtime_blocked_hosts,
198 const URLPatternSet& default_runtime_allowed_hosts) {
199 URLPatternSet* old_blocked = default_runtime_blocked_hosts_unsafe_;
200 default_runtime_blocked_hosts_unsafe_ =
201 new URLPatternSet(default_runtime_blocked_hosts);
202 delete old_blocked;
203 URLPatternSet* old_allowed = default_runtime_allowed_hosts_unsafe_;
204 default_runtime_allowed_hosts_unsafe_ =
205 new URLPatternSet(default_runtime_allowed_hosts);
206 delete old_allowed;
207 }
208
143 void PermissionsData::SetActivePermissions( 209 void PermissionsData::SetActivePermissions(
144 std::unique_ptr<const PermissionSet> active) const { 210 std::unique_ptr<const PermissionSet> active) const {
145 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); 211 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
146 active_permissions_unsafe_ = std::move(active); 212 active_permissions_unsafe_ = std::move(active);
147 } 213 }
148 214
149 void PermissionsData::UpdateTabSpecificPermissions( 215 void PermissionsData::UpdateTabSpecificPermissions(
150 int tab_id, 216 int tab_id,
151 const PermissionSet& permissions) const { 217 const PermissionSet& permissions) const {
152 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); 218 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { 267 URLPatternSet PermissionsData::GetEffectiveHostPermissions() const {
202 base::AutoLock auto_lock(runtime_lock_); 268 base::AutoLock auto_lock(runtime_lock_);
203 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts(); 269 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts();
204 for (const auto& val : tab_specific_permissions_) 270 for (const auto& val : tab_specific_permissions_)
205 effective_hosts.AddPatterns(val.second->effective_hosts()); 271 effective_hosts.AddPatterns(val.second->effective_hosts());
206 return effective_hosts; 272 return effective_hosts;
207 } 273 }
208 274
209 bool PermissionsData::HasHostPermission(const GURL& url) const { 275 bool PermissionsData::HasHostPermission(const GURL& url) const {
210 base::AutoLock auto_lock(runtime_lock_); 276 base::AutoLock auto_lock(runtime_lock_);
211 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url); 277 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url) &&
278 !IsRuntimeBlockedHost(url);
212 } 279 }
213 280
214 bool PermissionsData::HasEffectiveAccessToAllHosts() const { 281 bool PermissionsData::HasEffectiveAccessToAllHosts() const {
215 base::AutoLock auto_lock(runtime_lock_); 282 base::AutoLock auto_lock(runtime_lock_);
216 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); 283 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts();
217 } 284 }
218 285
219 PermissionMessages PermissionsData::GetPermissionMessages() const { 286 PermissionMessages PermissionsData::GetPermissionMessages() const {
220 base::AutoLock auto_lock(runtime_lock_); 287 base::AutoLock auto_lock(runtime_lock_);
221 return PermissionMessageProvider::Get()->GetPermissionMessages( 288 return PermissionMessageProvider::Get()->GetPermissionMessages(
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 if (tab_id >= 0) { 387 if (tab_id >= 0) {
321 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); 388 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id);
322 if (tab_permissions && 389 if (tab_permissions &&
323 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { 390 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) {
324 return true; 391 return true;
325 } 392 }
326 } 393 }
327 return false; 394 return false;
328 } 395 }
329 396
397 bool PermissionsData::IsRuntimeBlockedHost(const GURL& url) const {
398 return runtime_blocked_hosts().MatchesURL(url) &&
Devlin 2017/02/14 23:17:10 we can use the sets directly here.
nrpeter 2017/03/22 23:47:39 If we did, we'd end up duplicating the code to che
399 !runtime_allowed_hosts().MatchesURL(url);
400 }
401
330 PermissionsData::AccessType PermissionsData::CanRunOnPage( 402 PermissionsData::AccessType PermissionsData::CanRunOnPage(
331 const Extension* extension, 403 const Extension* extension,
332 const GURL& document_url, 404 const GURL& document_url,
333 int tab_id, 405 int tab_id,
334 const URLPatternSet& permitted_url_patterns, 406 const URLPatternSet& permitted_url_patterns,
335 const URLPatternSet& withheld_url_patterns, 407 const URLPatternSet& withheld_url_patterns,
336 std::string* error) const { 408 std::string* error) const {
337 runtime_lock_.AssertAcquired(); 409 runtime_lock_.AssertAcquired();
338 if (g_policy_delegate && 410 if (g_policy_delegate &&
339 !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url, 411 !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url,
340 tab_id, error)) { 412 tab_id, error))
413 return ACCESS_DENIED;
414
415 if (IsRuntimeBlockedHost(document_url)) {
416 if (error)
417 *error =
418 "This page cannot be scripted due to an ExtensionsSettings policy.";
341 return ACCESS_DENIED; 419 return ACCESS_DENIED;
342 } 420 }
343 421
344 if (IsRestrictedUrl(document_url, extension, error)) 422 if (IsRestrictedUrl(document_url, extension, error))
345 return ACCESS_DENIED; 423 return ACCESS_DENIED;
346 424
347 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url)) 425 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url))
348 return ACCESS_ALLOWED; 426 return ACCESS_ALLOWED;
349 427
350 if (permitted_url_patterns.MatchesURL(document_url)) 428 if (permitted_url_patterns.MatchesURL(document_url))
351 return ACCESS_ALLOWED; 429 return ACCESS_ALLOWED;
352 430
353 if (withheld_url_patterns.MatchesURL(document_url)) 431 if (withheld_url_patterns.MatchesURL(document_url))
354 return ACCESS_WITHHELD; 432 return ACCESS_WITHHELD;
355 433
356 if (error) { 434 if (error) {
357 if (extension->permissions_data()->active_permissions().HasAPIPermission( 435 if (extension->permissions_data()->active_permissions().HasAPIPermission(
358 APIPermission::kTab)) { 436 APIPermission::kTab)) {
359 *error = ErrorUtils::FormatErrorMessage( 437 *error = ErrorUtils::FormatErrorMessage(
360 manifest_errors::kCannotAccessPageWithUrl, document_url.spec()); 438 manifest_errors::kCannotAccessPageWithUrl, document_url.spec());
361 } else { 439 } else {
362 *error = manifest_errors::kCannotAccessPage; 440 *error = manifest_errors::kCannotAccessPage;
363 } 441 }
364 } 442 }
365 443
366 return ACCESS_DENIED; 444 return ACCESS_DENIED;
367 } 445 }
368 446
369 } // namespace extensions 447 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698