Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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_ = URLPatternSet(); | |
|
Devlin
2017/01/26 22:47:40
non-pod statics aren't allowed
nrpeter
2017/02/03 19:32:24
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_ = URLPatternSet(); | |
| 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 Loading... | |
| 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 Loading... | |
| 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 return default_runtime_blocked_hosts_unsafe_; | |
| 149 } | |
| 150 | |
| 151 const URLPatternSet& PermissionsData::default_runtime_allowed_hosts() { | |
| 152 return default_runtime_allowed_hosts_unsafe_; | |
| 153 } | |
| 154 | |
| 155 const URLPatternSet& PermissionsData::runtime_blocked_hosts() const { | |
| 156 if (uses_default_policy_host_restrictions_) | |
| 157 return default_runtime_blocked_hosts_unsafe_; | |
| 158 return runtime_blocked_hosts_unsafe_; | |
| 159 } | |
| 160 | |
| 161 const URLPatternSet& PermissionsData::runtime_allowed_hosts() const { | |
| 162 if (uses_default_policy_host_restrictions_) | |
| 163 return default_runtime_allowed_hosts_unsafe_; | |
| 164 return runtime_allowed_hosts_unsafe_; | |
| 165 } | |
| 166 | |
| 130 void PermissionsData::BindToCurrentThread() const { | 167 void PermissionsData::BindToCurrentThread() const { |
| 131 DCHECK(!thread_checker_); | 168 DCHECK(!thread_checker_); |
| 132 thread_checker_.reset(new base::ThreadChecker()); | 169 thread_checker_.reset(new base::ThreadChecker()); |
| 133 } | 170 } |
| 134 | 171 |
| 135 void PermissionsData::SetPermissions( | 172 void PermissionsData::SetPermissions( |
| 136 std::unique_ptr<const PermissionSet> active, | 173 std::unique_ptr<const PermissionSet> active, |
| 137 std::unique_ptr<const PermissionSet> withheld) const { | 174 std::unique_ptr<const PermissionSet> withheld) const { |
| 138 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); | 175 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
| 139 active_permissions_unsafe_ = std::move(active); | 176 active_permissions_unsafe_ = std::move(active); |
| 140 withheld_permissions_unsafe_ = std::move(withheld); | 177 withheld_permissions_unsafe_ = std::move(withheld); |
| 141 } | 178 } |
| 142 | 179 |
| 180 void PermissionsData::SetPolicyHostRestrictions( | |
| 181 const URLPatternSet runtime_blocked_hosts, | |
| 182 const URLPatternSet runtime_allowed_hosts, | |
| 183 const bool uses_default_policy_host_restrictions) const { | |
| 184 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); | |
| 185 runtime_blocked_hosts_unsafe_ = runtime_blocked_hosts; | |
| 186 runtime_allowed_hosts_unsafe_ = runtime_allowed_hosts; | |
| 187 uses_default_policy_host_restrictions_ = | |
| 188 uses_default_policy_host_restrictions; | |
| 189 } | |
| 190 | |
| 191 // static | |
| 192 void PermissionsData::SetDefaultPolicyHostRestrictions( | |
| 193 const URLPatternSet default_runtime_blocked_hosts, | |
| 194 const URLPatternSet default_runtime_allowed_hosts) { | |
| 195 default_runtime_blocked_hosts_unsafe_ = default_runtime_blocked_hosts; | |
| 196 default_runtime_allowed_hosts_unsafe_ = default_runtime_allowed_hosts; | |
| 197 } | |
| 198 | |
| 143 void PermissionsData::SetActivePermissions( | 199 void PermissionsData::SetActivePermissions( |
| 144 std::unique_ptr<const PermissionSet> active) const { | 200 std::unique_ptr<const PermissionSet> active) const { |
| 145 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); | 201 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
| 146 active_permissions_unsafe_ = std::move(active); | 202 active_permissions_unsafe_ = std::move(active); |
| 147 } | 203 } |
| 148 | 204 |
| 149 void PermissionsData::UpdateTabSpecificPermissions( | 205 void PermissionsData::UpdateTabSpecificPermissions( |
| 150 int tab_id, | 206 int tab_id, |
| 151 const PermissionSet& permissions) const { | 207 const PermissionSet& permissions) const { |
| 152 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); | 208 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { | 257 URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { |
| 202 base::AutoLock auto_lock(runtime_lock_); | 258 base::AutoLock auto_lock(runtime_lock_); |
| 203 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts(); | 259 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts(); |
| 204 for (const auto& val : tab_specific_permissions_) | 260 for (const auto& val : tab_specific_permissions_) |
| 205 effective_hosts.AddPatterns(val.second->effective_hosts()); | 261 effective_hosts.AddPatterns(val.second->effective_hosts()); |
| 206 return effective_hosts; | 262 return effective_hosts; |
| 207 } | 263 } |
| 208 | 264 |
| 209 bool PermissionsData::HasHostPermission(const GURL& url) const { | 265 bool PermissionsData::HasHostPermission(const GURL& url) const { |
| 210 base::AutoLock auto_lock(runtime_lock_); | 266 base::AutoLock auto_lock(runtime_lock_); |
| 211 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url); | 267 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url) && |
| 268 !IsRuntimeBlockedHost(url); | |
| 212 } | 269 } |
| 213 | 270 |
| 214 bool PermissionsData::HasEffectiveAccessToAllHosts() const { | 271 bool PermissionsData::HasEffectiveAccessToAllHosts() const { |
| 215 base::AutoLock auto_lock(runtime_lock_); | 272 base::AutoLock auto_lock(runtime_lock_); |
| 216 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); | 273 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); |
| 217 } | 274 } |
| 218 | 275 |
| 219 PermissionMessages PermissionsData::GetPermissionMessages() const { | 276 PermissionMessages PermissionsData::GetPermissionMessages() const { |
| 220 base::AutoLock auto_lock(runtime_lock_); | 277 base::AutoLock auto_lock(runtime_lock_); |
| 221 return PermissionMessageProvider::Get()->GetPermissionMessages( | 278 return PermissionMessageProvider::Get()->GetPermissionMessages( |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 if (tab_id >= 0) { | 377 if (tab_id >= 0) { |
| 321 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); | 378 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); |
| 322 if (tab_permissions && | 379 if (tab_permissions && |
| 323 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { | 380 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { |
| 324 return true; | 381 return true; |
| 325 } | 382 } |
| 326 } | 383 } |
| 327 return false; | 384 return false; |
| 328 } | 385 } |
| 329 | 386 |
| 387 bool PermissionsData::IsRuntimeBlockedHost(const GURL& url) const { | |
| 388 return runtime_blocked_hosts().MatchesURL(url) && | |
| 389 !runtime_allowed_hosts().MatchesURL(url); | |
| 390 } | |
| 391 | |
| 330 PermissionsData::AccessType PermissionsData::CanRunOnPage( | 392 PermissionsData::AccessType PermissionsData::CanRunOnPage( |
| 331 const Extension* extension, | 393 const Extension* extension, |
| 332 const GURL& document_url, | 394 const GURL& document_url, |
| 333 int tab_id, | 395 int tab_id, |
| 334 const URLPatternSet& permitted_url_patterns, | 396 const URLPatternSet& permitted_url_patterns, |
| 335 const URLPatternSet& withheld_url_patterns, | 397 const URLPatternSet& withheld_url_patterns, |
| 336 std::string* error) const { | 398 std::string* error) const { |
| 337 runtime_lock_.AssertAcquired(); | 399 runtime_lock_.AssertAcquired(); |
| 338 if (g_policy_delegate && | 400 if (g_policy_delegate && |
| 339 !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url, | 401 !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url, |
| 340 tab_id, error)) { | 402 tab_id, error)) |
| 403 return ACCESS_DENIED; | |
| 404 | |
| 405 if (IsRuntimeBlockedHost(document_url)) { | |
| 406 if (error) | |
| 407 *error = | |
| 408 "This page cannot be scripted due to an ExtensionsSettings policy."; | |
| 341 return ACCESS_DENIED; | 409 return ACCESS_DENIED; |
| 342 } | 410 } |
| 343 | 411 |
| 344 if (IsRestrictedUrl(document_url, extension, error)) | 412 if (IsRestrictedUrl(document_url, extension, error)) |
| 345 return ACCESS_DENIED; | 413 return ACCESS_DENIED; |
| 346 | 414 |
| 347 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url)) | 415 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url)) |
| 348 return ACCESS_ALLOWED; | 416 return ACCESS_ALLOWED; |
| 349 | 417 |
| 350 if (permitted_url_patterns.MatchesURL(document_url)) | 418 if (permitted_url_patterns.MatchesURL(document_url)) |
| 351 return ACCESS_ALLOWED; | 419 return ACCESS_ALLOWED; |
| 352 | 420 |
| 353 if (withheld_url_patterns.MatchesURL(document_url)) | 421 if (withheld_url_patterns.MatchesURL(document_url)) |
| 354 return ACCESS_WITHHELD; | 422 return ACCESS_WITHHELD; |
| 355 | 423 |
| 356 if (error) { | 424 if (error) { |
| 357 if (extension->permissions_data()->active_permissions().HasAPIPermission( | 425 if (extension->permissions_data()->active_permissions().HasAPIPermission( |
| 358 APIPermission::kTab)) { | 426 APIPermission::kTab)) { |
| 359 *error = ErrorUtils::FormatErrorMessage( | 427 *error = ErrorUtils::FormatErrorMessage( |
| 360 manifest_errors::kCannotAccessPageWithUrl, document_url.spec()); | 428 manifest_errors::kCannotAccessPageWithUrl, document_url.spec()); |
| 361 } else { | 429 } else { |
| 362 *error = manifest_errors::kCannotAccessPage; | 430 *error = manifest_errors::kCannotAccessPage; |
| 363 } | 431 } |
| 364 } | 432 } |
| 365 | 433 |
| 366 return ACCESS_DENIED; | 434 return ACCESS_DENIED; |
| 367 } | 435 } |
| 368 | 436 |
| 369 } // namespace extensions | 437 } // namespace extensions |
| OLD | NEW |