Chromium Code Reviews| Index: extensions/common/permissions/permissions_data.cc |
| diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc |
| index 4025d23c0ff0096e075b60521ae95bb0b0e5675c..60a74aa52ce0fe438f535cc62f608cbf3e4ab156 100644 |
| --- a/extensions/common/permissions/permissions_data.cc |
| +++ b/extensions/common/permissions/permissions_data.cc |
| @@ -8,6 +8,7 @@ |
| #include <utility> |
| #include "base/command_line.h" |
| +#include "base/lazy_instance.h" |
| #include "base/macros.h" |
| #include "content/public/common/url_constants.h" |
| #include "extensions/common/constants.h" |
| @@ -30,6 +31,16 @@ namespace { |
| PermissionsData::PolicyDelegate* g_policy_delegate = nullptr; |
| +struct DefaultRuntimePolicy { |
| + URLPatternSet blocked_hosts; |
| + URLPatternSet allowed_hosts; |
| +}; |
| +// URLs an extension can't interact with. An extension can override these |
| +// settings by declaring its own list of blocked and allowed hosts using |
| +// policy_blocked_hosts and policy_allowed_hosts. |
| +base::LazyInstance<DefaultRuntimePolicy>::Leaky default_runtime_policy = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| class AutoLockOnValidThread { |
| public: |
| AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker) |
| @@ -87,6 +98,11 @@ bool PermissionsData::ShouldSkipPermissionWarnings( |
| bool PermissionsData::IsRestrictedUrl(const GURL& document_url, |
| const Extension* extension, |
| std::string* error) { |
| + if (extension && |
| + extension->permissions_data()->IsRuntimeBlockedHost(document_url)) { |
| + *error = manifest_errors::kCannotAccessPage; |
| + return true; |
| + } |
| if (extension && CanExecuteScriptEverywhere(extension)) |
| return false; |
| @@ -127,6 +143,33 @@ bool PermissionsData::IsRestrictedUrl(const GURL& document_url, |
| return false; |
| } |
| +bool PermissionsData::UsesDefaultPolicyHostRestrictions() const { |
| + DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread()); |
| + return uses_default_policy_host_restrictions; |
| +} |
| + |
| +const URLPatternSet& PermissionsData::default_policy_blocked_hosts() { |
| + return default_runtime_policy.Get().blocked_hosts; |
| +} |
| + |
| +const URLPatternSet& PermissionsData::default_policy_allowed_hosts() { |
| + return default_runtime_policy.Get().allowed_hosts; |
| +} |
| + |
| +const URLPatternSet& PermissionsData::policy_blocked_hosts() const { |
| + DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread()); |
| + if (uses_default_policy_host_restrictions) |
| + return default_policy_blocked_hosts(); |
| + return policy_blocked_hosts_unsafe_; |
| +} |
| + |
| +const URLPatternSet& PermissionsData::policy_allowed_hosts() const { |
| + DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread()); |
| + if (uses_default_policy_host_restrictions) |
| + return default_policy_allowed_hosts(); |
| + return policy_allowed_hosts_unsafe_; |
| +} |
| + |
| void PermissionsData::BindToCurrentThread() const { |
| DCHECK(!thread_checker_); |
| thread_checker_.reset(new base::ThreadChecker()); |
| @@ -140,6 +183,27 @@ void PermissionsData::SetPermissions( |
| withheld_permissions_unsafe_ = std::move(withheld); |
| } |
| +void PermissionsData::SetPolicyHostRestrictions( |
| + const URLPatternSet& runtime_blocked_hosts, |
| + const URLPatternSet& runtime_allowed_hosts) const { |
| + AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
| + 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.
|
| + policy_allowed_hosts_unsafe_ = runtime_allowed_hosts; |
| +} |
| + |
| +void PermissionsData::SetUsesDefaultHostRestrictions( |
| + bool uses_default_restrictions) const { |
| + uses_default_policy_host_restrictions = uses_default_restrictions; |
| +} |
| + |
| +// static |
| +void PermissionsData::SetDefaultPolicyHostRestrictions( |
| + const URLPatternSet& default_runtime_blocked_hosts, |
| + const URLPatternSet& default_runtime_allowed_hosts) { |
| + default_runtime_policy.Get().blocked_hosts = default_runtime_blocked_hosts; |
| + default_runtime_policy.Get().allowed_hosts = default_runtime_allowed_hosts; |
| +} |
| + |
| void PermissionsData::SetActivePermissions( |
| std::unique_ptr<const PermissionSet> active) const { |
| AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
| @@ -208,7 +272,8 @@ URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { |
| bool PermissionsData::HasHostPermission(const GURL& url) const { |
| base::AutoLock auto_lock(runtime_lock_); |
| - return active_permissions_unsafe_->HasExplicitAccessToOrigin(url); |
| + return active_permissions_unsafe_->HasExplicitAccessToOrigin(url) && |
| + !IsRuntimeBlockedHost(url); |
| } |
| bool PermissionsData::HasEffectiveAccessToAllHosts() const { |
| @@ -327,6 +392,11 @@ bool PermissionsData::HasTabSpecificPermissionToExecuteScript( |
| return false; |
| } |
| +bool PermissionsData::IsRuntimeBlockedHost(const GURL& url) const { |
| + return policy_blocked_hosts().MatchesURL(url) && |
| + !policy_allowed_hosts().MatchesURL(url); |
| +} |
| + |
| PermissionsData::AccessType PermissionsData::CanRunOnPage( |
| const Extension* extension, |
| const GURL& document_url, |
| @@ -337,7 +407,13 @@ PermissionsData::AccessType PermissionsData::CanRunOnPage( |
| runtime_lock_.AssertAcquired(); |
| if (g_policy_delegate && |
| !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url, |
| - tab_id, error)) { |
| + tab_id, error)) |
| + return ACCESS_DENIED; |
| + |
| + if (IsRuntimeBlockedHost(document_url)) { |
| + if (error) |
| + *error = |
| + "This page cannot be scripted due to an ExtensionsSettings policy."; |
| return ACCESS_DENIED; |
| } |