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" |
| 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 |
| 39 // URLs an extension can't interact with. An extension can override these |
| 40 // settings by declaring its own list of blocked and allowed hosts using |
| 41 // policy_blocked_hosts and policy_allowed_hosts. |
| 42 base::LazyInstance<DefaultRuntimePolicy>::Leaky default_runtime_policy = |
| 43 LAZY_INSTANCE_INITIALIZER; |
| 44 |
33 class AutoLockOnValidThread { | 45 class AutoLockOnValidThread { |
34 public: | 46 public: |
35 AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker) | 47 AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker) |
36 : auto_lock_(lock) { | 48 : auto_lock_(lock) { |
37 DCHECK(!thread_checker || thread_checker->CalledOnValidThread()); | 49 DCHECK(!thread_checker || thread_checker->CalledOnValidThread()); |
38 } | 50 } |
39 | 51 |
40 private: | 52 private: |
41 base::AutoLock auto_lock_; | 53 base::AutoLock auto_lock_; |
42 | 54 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after 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_policy_blocked_hosts() { |
| 148 return default_runtime_policy.Get().blocked_hosts; |
| 149 } |
| 150 |
| 151 const URLPatternSet& PermissionsData::default_policy_allowed_hosts() { |
| 152 return default_runtime_policy.Get().allowed_hosts; |
| 153 } |
| 154 |
| 155 const URLPatternSet PermissionsData::policy_blocked_hosts() const { |
| 156 base::AutoLock auto_lock(runtime_lock_); |
| 157 return PolicyBlockedHostsUnsafe(); |
| 158 } |
| 159 |
| 160 const URLPatternSet& PermissionsData::PolicyBlockedHostsUnsafe() const { |
| 161 DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread()); |
| 162 if (uses_default_policy_host_restrictions) |
| 163 return default_policy_blocked_hosts(); |
| 164 runtime_lock_.AssertAcquired(); |
| 165 return policy_blocked_hosts_unsafe_; |
| 166 } |
| 167 |
| 168 const URLPatternSet PermissionsData::policy_allowed_hosts() const { |
| 169 base::AutoLock auto_lock(runtime_lock_); |
| 170 return PolicyAllowedHostsUnsafe(); |
| 171 } |
| 172 |
| 173 const URLPatternSet& PermissionsData::PolicyAllowedHostsUnsafe() const { |
| 174 DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread()); |
| 175 if (uses_default_policy_host_restrictions) |
| 176 return default_policy_allowed_hosts(); |
| 177 runtime_lock_.AssertAcquired(); |
| 178 return policy_allowed_hosts_unsafe_; |
| 179 } |
| 180 |
130 void PermissionsData::BindToCurrentThread() const { | 181 void PermissionsData::BindToCurrentThread() const { |
131 DCHECK(!thread_checker_); | 182 DCHECK(!thread_checker_); |
132 thread_checker_.reset(new base::ThreadChecker()); | 183 thread_checker_.reset(new base::ThreadChecker()); |
133 } | 184 } |
134 | 185 |
135 void PermissionsData::SetPermissions( | 186 void PermissionsData::SetPermissions( |
136 std::unique_ptr<const PermissionSet> active, | 187 std::unique_ptr<const PermissionSet> active, |
137 std::unique_ptr<const PermissionSet> withheld) const { | 188 std::unique_ptr<const PermissionSet> withheld) const { |
138 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); | 189 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
139 active_permissions_unsafe_ = std::move(active); | 190 active_permissions_unsafe_ = std::move(active); |
140 withheld_permissions_unsafe_ = std::move(withheld); | 191 withheld_permissions_unsafe_ = std::move(withheld); |
141 } | 192 } |
142 | 193 |
| 194 void PermissionsData::SetPolicyHostRestrictions( |
| 195 const URLPatternSet& runtime_blocked_hosts, |
| 196 const URLPatternSet& runtime_allowed_hosts) const { |
| 197 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
| 198 policy_blocked_hosts_unsafe_ = runtime_blocked_hosts; |
| 199 policy_allowed_hosts_unsafe_ = runtime_allowed_hosts; |
| 200 uses_default_policy_host_restrictions = false; |
| 201 } |
| 202 |
| 203 void PermissionsData::SetUsesDefaultHostRestrictions() const { |
| 204 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
| 205 uses_default_policy_host_restrictions = true; |
| 206 } |
| 207 |
| 208 // static |
| 209 void PermissionsData::SetDefaultPolicyHostRestrictions( |
| 210 const URLPatternSet& default_runtime_blocked_hosts, |
| 211 const URLPatternSet& default_runtime_allowed_hosts) { |
| 212 default_runtime_policy.Get().blocked_hosts = default_runtime_blocked_hosts; |
| 213 default_runtime_policy.Get().allowed_hosts = default_runtime_allowed_hosts; |
| 214 } |
| 215 |
143 void PermissionsData::SetActivePermissions( | 216 void PermissionsData::SetActivePermissions( |
144 std::unique_ptr<const PermissionSet> active) const { | 217 std::unique_ptr<const PermissionSet> active) const { |
145 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); | 218 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); |
146 active_permissions_unsafe_ = std::move(active); | 219 active_permissions_unsafe_ = std::move(active); |
147 } | 220 } |
148 | 221 |
149 void PermissionsData::UpdateTabSpecificPermissions( | 222 void PermissionsData::UpdateTabSpecificPermissions( |
150 int tab_id, | 223 int tab_id, |
151 const PermissionSet& permissions) const { | 224 const PermissionSet& permissions) const { |
152 AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); | 225 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 { | 274 URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { |
202 base::AutoLock auto_lock(runtime_lock_); | 275 base::AutoLock auto_lock(runtime_lock_); |
203 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts(); | 276 URLPatternSet effective_hosts = active_permissions_unsafe_->effective_hosts(); |
204 for (const auto& val : tab_specific_permissions_) | 277 for (const auto& val : tab_specific_permissions_) |
205 effective_hosts.AddPatterns(val.second->effective_hosts()); | 278 effective_hosts.AddPatterns(val.second->effective_hosts()); |
206 return effective_hosts; | 279 return effective_hosts; |
207 } | 280 } |
208 | 281 |
209 bool PermissionsData::HasHostPermission(const GURL& url) const { | 282 bool PermissionsData::HasHostPermission(const GURL& url) const { |
210 base::AutoLock auto_lock(runtime_lock_); | 283 base::AutoLock auto_lock(runtime_lock_); |
211 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url); | 284 return active_permissions_unsafe_->HasExplicitAccessToOrigin(url) && |
| 285 !IsRuntimeBlockedHost(url); |
212 } | 286 } |
213 | 287 |
214 bool PermissionsData::HasEffectiveAccessToAllHosts() const { | 288 bool PermissionsData::HasEffectiveAccessToAllHosts() const { |
215 base::AutoLock auto_lock(runtime_lock_); | 289 base::AutoLock auto_lock(runtime_lock_); |
216 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); | 290 return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); |
217 } | 291 } |
218 | 292 |
219 PermissionMessages PermissionsData::GetPermissionMessages() const { | 293 PermissionMessages PermissionsData::GetPermissionMessages() const { |
220 base::AutoLock auto_lock(runtime_lock_); | 294 base::AutoLock auto_lock(runtime_lock_); |
221 return PermissionMessageProvider::Get()->GetPermissionMessages( | 295 return PermissionMessageProvider::Get()->GetPermissionMessages( |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 if (tab_id >= 0) { | 394 if (tab_id >= 0) { |
321 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); | 395 const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); |
322 if (tab_permissions && | 396 if (tab_permissions && |
323 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { | 397 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { |
324 return true; | 398 return true; |
325 } | 399 } |
326 } | 400 } |
327 return false; | 401 return false; |
328 } | 402 } |
329 | 403 |
| 404 bool PermissionsData::IsRuntimeBlockedHost(const GURL& url) const { |
| 405 runtime_lock_.AssertAcquired(); |
| 406 return PolicyBlockedHostsUnsafe().MatchesURL(url) && |
| 407 !PolicyAllowedHostsUnsafe().MatchesURL(url); |
| 408 } |
| 409 |
330 PermissionsData::AccessType PermissionsData::CanRunOnPage( | 410 PermissionsData::AccessType PermissionsData::CanRunOnPage( |
331 const Extension* extension, | 411 const Extension* extension, |
332 const GURL& document_url, | 412 const GURL& document_url, |
333 int tab_id, | 413 int tab_id, |
334 const URLPatternSet& permitted_url_patterns, | 414 const URLPatternSet& permitted_url_patterns, |
335 const URLPatternSet& withheld_url_patterns, | 415 const URLPatternSet& withheld_url_patterns, |
336 std::string* error) const { | 416 std::string* error) const { |
337 runtime_lock_.AssertAcquired(); | 417 runtime_lock_.AssertAcquired(); |
338 if (g_policy_delegate && | 418 if (g_policy_delegate && !g_policy_delegate->CanExecuteScriptOnPage( |
339 !g_policy_delegate->CanExecuteScriptOnPage(extension, document_url, | 419 extension, document_url, tab_id, error)) |
340 tab_id, error)) { | 420 return ACCESS_DENIED; |
| 421 |
| 422 if (extension->location() != Manifest::COMPONENT && |
| 423 extension->permissions_data()->IsRuntimeBlockedHost(document_url)) { |
| 424 if (error) |
| 425 *error = extension_misc::kPolicyBlockedScripting; |
341 return ACCESS_DENIED; | 426 return ACCESS_DENIED; |
342 } | 427 } |
343 | 428 |
344 if (IsRestrictedUrl(document_url, extension, error)) | 429 if (IsRestrictedUrl(document_url, extension, error)) |
345 return ACCESS_DENIED; | 430 return ACCESS_DENIED; |
346 | 431 |
347 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url)) | 432 if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url)) |
348 return ACCESS_ALLOWED; | 433 return ACCESS_ALLOWED; |
349 | 434 |
350 if (permitted_url_patterns.MatchesURL(document_url)) | 435 if (permitted_url_patterns.MatchesURL(document_url)) |
351 return ACCESS_ALLOWED; | 436 return ACCESS_ALLOWED; |
352 | 437 |
353 if (withheld_url_patterns.MatchesURL(document_url)) | 438 if (withheld_url_patterns.MatchesURL(document_url)) |
354 return ACCESS_WITHHELD; | 439 return ACCESS_WITHHELD; |
355 | 440 |
356 if (error) { | 441 if (error) { |
357 if (extension->permissions_data()->active_permissions().HasAPIPermission( | 442 if (extension->permissions_data()->active_permissions().HasAPIPermission( |
358 APIPermission::kTab)) { | 443 APIPermission::kTab)) { |
359 *error = ErrorUtils::FormatErrorMessage( | 444 *error = ErrorUtils::FormatErrorMessage( |
360 manifest_errors::kCannotAccessPageWithUrl, document_url.spec()); | 445 manifest_errors::kCannotAccessPageWithUrl, document_url.spec()); |
361 } else { | 446 } else { |
362 *error = manifest_errors::kCannotAccessPage; | 447 *error = manifest_errors::kCannotAccessPage; |
363 } | 448 } |
364 } | 449 } |
365 | 450 |
366 return ACCESS_DENIED; | 451 return ACCESS_DENIED; |
367 } | 452 } |
368 | 453 |
369 } // namespace extensions | 454 } // namespace extensions |
OLD | NEW |