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

Side by Side Diff: chrome/common/extensions/permissions/permission_set.cc

Issue 18399007: Don't count host permission changes for v2 apps as a permission increase. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: refactor Created 7 years, 5 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 | Annotate | Revision Log
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 "chrome/common/extensions/permissions/permission_set.h" 5 #include "chrome/common/extensions/permissions/permission_set.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <string> 9 #include <string>
10 10
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 // Functions will be of the form api_name.function 87 // Functions will be of the form api_name.function
88 // Events will be of the form api_name/id or api_name.optional.stuff 88 // Events will be of the form api_name/id or api_name.optional.stuff
89 std::string GetPermissionName(const std::string& function_name) { 89 std::string GetPermissionName(const std::string& function_name) {
90 size_t separator = function_name.find_first_of("./"); 90 size_t separator = function_name.find_first_of("./");
91 if (separator != std::string::npos) 91 if (separator != std::string::npos)
92 return function_name.substr(0, separator); 92 return function_name.substr(0, separator);
93 else 93 else
94 return function_name; 94 return function_name;
95 } 95 }
96 96
97
98
97 } // namespace 99 } // namespace
98 100
99 namespace extensions { 101 namespace extensions {
100 102
101 // 103 //
102 // PermissionSet 104 // PermissionSet
103 // 105 //
104 106
105 PermissionSet::PermissionSet() {} 107 PermissionSet::PermissionSet() {}
106 108
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 Manifest::Type extension_type) const { 258 Manifest::Type extension_type) const {
257 PermissionMessages messages; 259 PermissionMessages messages;
258 260
259 if (HasEffectiveFullAccess()) { 261 if (HasEffectiveFullAccess()) {
260 messages.push_back(PermissionMessage( 262 messages.push_back(PermissionMessage(
261 PermissionMessage::kFullAccess, 263 PermissionMessage::kFullAccess,
262 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS))); 264 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS)));
263 return messages; 265 return messages;
264 } 266 }
265 267
266 // Since platform apps always use isolated storage, they can't (silently) 268 std::set<PermissionMessage> host_msgs =
267 // access user data on other domains, so there's no need to prompt. 269 GetHostPermissionMessages(extension_type);
268 if (extension_type != Manifest::TYPE_PLATFORM_APP) { 270 std::set<PermissionMessage> api_msgs = GetAPIPermissionMessages();
269 if (HasEffectiveAccessToAllHosts()) { 271 messages.insert(messages.end(), host_msgs.begin(), host_msgs.end());
270 messages.push_back(PermissionMessage( 272 messages.insert(messages.end(), api_msgs.begin(), api_msgs.end());
271 PermissionMessage::kHostsAll,
272 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
273 } else {
274 for (URLPatternSet::const_iterator i = effective_hosts_.begin();
275 i != effective_hosts_.end(); ++i) {
276 if (i->scheme() != chrome::kChromeUIScheme)
277 continue;
278 // chrome://favicon is the only URL for chrome:// scheme that we
279 // want to support. We want to deprecate the "chrome" scheme.
280 // We should not add any additional "host" here.
281 if (GURL(chrome::kChromeUIFaviconURL).host() != i->host())
282 continue;
283 messages.push_back(PermissionMessage(
284 PermissionMessage::kFavicon,
285 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FAVICON)));
286 }
287 std::set<std::string> hosts = GetDistinctHostsForDisplay();
288 if (!hosts.empty())
289 messages.push_back(PermissionMessage::CreateFromHostList(hosts));
290 }
291 }
292
293 std::set<PermissionMessage> simple_msgs =
294 GetSimplePermissionMessages();
295 messages.insert(messages.end(), simple_msgs.begin(), simple_msgs.end());
296 273
297 return messages; 274 return messages;
298 } 275 }
299 276
300 std::vector<string16> PermissionSet::GetWarningMessages( 277 std::vector<string16> PermissionSet::GetWarningMessages(
301 Manifest::Type extension_type) const { 278 Manifest::Type extension_type) const {
302 std::vector<string16> messages; 279 std::vector<string16> messages;
303 PermissionMessages permissions = GetPermissionMessages(extension_type); 280 PermissionMessages permissions = GetPermissionMessages(extension_type);
304 281
305 bool audio_capture = false; 282 bool audio_capture = false;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 bool PermissionSet::HasEffectiveFullAccess() const { 414 bool PermissionSet::HasEffectiveFullAccess() const {
438 for (APIPermissionSet::const_iterator i = apis().begin(); 415 for (APIPermissionSet::const_iterator i = apis().begin();
439 i != apis().end(); ++i) { 416 i != apis().end(); ++i) {
440 if (i->info()->implies_full_access()) 417 if (i->info()->implies_full_access())
441 return true; 418 return true;
442 } 419 }
443 return false; 420 return false;
444 } 421 }
445 422
446 bool PermissionSet::HasLessPrivilegesThan( 423 bool PermissionSet::HasLessPrivilegesThan(
447 const PermissionSet* permissions) const { 424 const PermissionSet* permissions,
425 Manifest::Type extension_type) const {
448 // Things can't get worse than native code access. 426 // Things can't get worse than native code access.
449 if (HasEffectiveFullAccess()) 427 if (HasEffectiveFullAccess())
450 return false; 428 return false;
451 429
452 // Otherwise, it's a privilege increase if the new one has full access. 430 // Otherwise, it's a privilege increase if the new one has full access.
453 if (permissions->HasEffectiveFullAccess()) 431 if (permissions->HasEffectiveFullAccess())
454 return true; 432 return true;
455 433
456 if (HasLessHostPrivilegesThan(permissions)) 434 if (HasLessHostPrivilegesThan(permissions, extension_type))
457 return true; 435 return true;
458 436
459 if (HasLessAPIPrivilegesThan(permissions)) 437 if (HasLessAPIPrivilegesThan(permissions))
460 return true; 438 return true;
461 439
462 return false; 440 return false;
463 } 441 }
464 442
465 PermissionSet::~PermissionSet() {} 443 PermissionSet::~PermissionSet() {}
466 444
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 apis_.insert(APIPermission::kFileBrowserHandlerInternal); 517 apis_.insert(APIPermission::kFileBrowserHandlerInternal);
540 } 518 }
541 519
542 void PermissionSet::InitEffectiveHosts() { 520 void PermissionSet::InitEffectiveHosts() {
543 effective_hosts_.ClearPatterns(); 521 effective_hosts_.ClearPatterns();
544 522
545 URLPatternSet::CreateUnion( 523 URLPatternSet::CreateUnion(
546 explicit_hosts(), scriptable_hosts(), &effective_hosts_); 524 explicit_hosts(), scriptable_hosts(), &effective_hosts_);
547 } 525 }
548 526
549 std::set<PermissionMessage> 527 std::set<PermissionMessage> PermissionSet::GetAPIPermissionMessages() const {
550 PermissionSet::GetSimplePermissionMessages() const {
551 std::set<PermissionMessage> messages; 528 std::set<PermissionMessage> messages;
552 for (APIPermissionSet::const_iterator permission_it = apis_.begin(); 529 for (APIPermissionSet::const_iterator permission_it = apis_.begin();
553 permission_it != apis_.end(); ++permission_it) { 530 permission_it != apis_.end(); ++permission_it) {
554 DCHECK_GT(PermissionMessage::kNone, 531 DCHECK_GT(PermissionMessage::kNone,
555 PermissionMessage::kUnknown); 532 PermissionMessage::kUnknown);
556 if (permission_it->HasMessages()) { 533 if (permission_it->HasMessages()) {
557 PermissionMessages new_messages = permission_it->GetMessages(); 534 PermissionMessages new_messages = permission_it->GetMessages();
558 messages.insert(new_messages.begin(), new_messages.end()); 535 messages.insert(new_messages.begin(), new_messages.end());
559 } 536 }
560 } 537 }
561 return messages; 538 return messages;
562 } 539 }
563 540
541 std::set<PermissionMessage> PermissionSet::GetHostPermissionMessages(
542 Manifest::Type extension_type) const {
543 // Since platform apps always use isolated storage, they can't (silently)
544 // access user data on other domains, so there's no need to prompt.
545 // Note: this must remain consistent with HasLessHostPrivilegesThan.
546 // See crbug.com/255229.
547 std::set<PermissionMessage> messages;
548 if (extension_type == Manifest::TYPE_PLATFORM_APP)
549 return messages;
550
551 if (HasEffectiveAccessToAllHosts()) {
552 messages.insert(PermissionMessage(
553 PermissionMessage::kHostsAll,
554 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
555 } else {
556 for (URLPatternSet::const_iterator i = effective_hosts_.begin();
557 i != effective_hosts_.end(); ++i) {
558 if (i->scheme() != chrome::kChromeUIScheme)
559 continue;
560 // chrome://favicon is the only URL for chrome:// scheme that we
561 // want to support. We want to deprecate the "chrome" scheme.
562 // We should not add any additional "host" here.
563 if (GURL(chrome::kChromeUIFaviconURL).host() != i->host())
564 continue;
565 messages.insert(PermissionMessage(
566 PermissionMessage::kFavicon,
567 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FAVICON)));
568 }
569 std::set<std::string> hosts = GetDistinctHostsForDisplay();
570 if (!hosts.empty())
571 messages.insert(PermissionMessage::CreateFromHostList(hosts));
572 }
573 return messages;
574 }
575
564 bool PermissionSet::HasLessAPIPrivilegesThan( 576 bool PermissionSet::HasLessAPIPrivilegesThan(
565 const PermissionSet* permissions) const { 577 const PermissionSet* permissions) const {
566 if (permissions == NULL) 578 if (permissions == NULL)
567 return false; 579 return false;
568 580
569 std::set<PermissionMessage> current_warnings = 581 std::set<PermissionMessage> current_warnings =
570 GetSimplePermissionMessages(); 582 GetAPIPermissionMessages();
571 std::set<PermissionMessage> new_warnings = 583 std::set<PermissionMessage> new_warnings =
572 permissions->GetSimplePermissionMessages(); 584 permissions->GetAPIPermissionMessages();
573 std::set<PermissionMessage> delta_warnings; 585 std::set<PermissionMessage> delta_warnings;
574 std::set_difference(new_warnings.begin(), new_warnings.end(), 586 std::set_difference(new_warnings.begin(), new_warnings.end(),
575 current_warnings.begin(), current_warnings.end(), 587 current_warnings.begin(), current_warnings.end(),
576 std::inserter(delta_warnings, delta_warnings.begin())); 588 std::inserter(delta_warnings, delta_warnings.begin()));
577 589
578 // We have less privileges if there are additional warnings present. 590 // We have less privileges if there are additional warnings present.
579 return !delta_warnings.empty(); 591 return !delta_warnings.empty();
580 } 592 }
581 593
582 bool PermissionSet::HasLessHostPrivilegesThan( 594 bool PermissionSet::HasLessHostPrivilegesThan(
583 const PermissionSet* permissions) const { 595 const PermissionSet* permissions,
596 Manifest::Type extension_type) const {
597 // Platform apps host permission changes do not count as privilege increases.
598 // Note: this must remain consistent with GetHostPermissionMessages.
599 if (extension_type == Manifest::TYPE_PLATFORM_APP)
600 return false;
601
584 // If this permission set can access any host, then it can't be elevated. 602 // If this permission set can access any host, then it can't be elevated.
585 if (HasEffectiveAccessToAllHosts()) 603 if (HasEffectiveAccessToAllHosts())
586 return false; 604 return false;
587 605
588 // Likewise, if the other permission set has full host access, then it must be 606 // Likewise, if the other permission set has full host access, then it must be
589 // a privilege increase. 607 // a privilege increase.
590 if (permissions->HasEffectiveAccessToAllHosts()) 608 if (permissions->HasEffectiveAccessToAllHosts())
591 return true; 609 return true;
592 610
593 const URLPatternSet& old_list = effective_hosts(); 611 const URLPatternSet& old_list = effective_hosts();
594 const URLPatternSet& new_list = permissions->effective_hosts(); 612 const URLPatternSet& new_list = permissions->effective_hosts();
595 613
596 // TODO(jstritar): This is overly conservative with respect to subdomains. 614 // TODO(jstritar): This is overly conservative with respect to subdomains.
597 // For example, going from *.google.com to www.google.com will be 615 // For example, going from *.google.com to www.google.com will be
598 // considered an elevation, even though it is not (http://crbug.com/65337). 616 // considered an elevation, even though it is not (http://crbug.com/65337).
599 std::set<std::string> new_hosts_set(GetDistinctHosts(new_list, false, false)); 617 std::set<std::string> new_hosts_set(GetDistinctHosts(new_list, false, false));
600 std::set<std::string> old_hosts_set(GetDistinctHosts(old_list, false, false)); 618 std::set<std::string> old_hosts_set(GetDistinctHosts(old_list, false, false));
601 std::set<std::string> new_hosts_only; 619 std::set<std::string> new_hosts_only;
602 620
603 std::set_difference(new_hosts_set.begin(), new_hosts_set.end(), 621 std::set_difference(new_hosts_set.begin(), new_hosts_set.end(),
604 old_hosts_set.begin(), old_hosts_set.end(), 622 old_hosts_set.begin(), old_hosts_set.end(),
605 std::inserter(new_hosts_only, new_hosts_only.begin())); 623 std::inserter(new_hosts_only, new_hosts_only.begin()));
606 624
607 return !new_hosts_only.empty(); 625 return !new_hosts_only.empty();
608 } 626 }
609 627
610 } // namespace extensions 628 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698