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

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: rebase 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 PermissionMessages additional_warnings =
275 GetChromeSchemePermissionWarnings(effective_hosts_);
276 for (size_t i = 0; i < additional_warnings.size(); ++i)
277 messages.push_back(additional_warnings[i]);
278
279 std::set<std::string> hosts = GetDistinctHostsForDisplay();
280 if (!hosts.empty())
281 messages.push_back(PermissionMessage::CreateFromHostList(hosts));
282 }
283 }
284
285 std::set<PermissionMessage> simple_msgs =
286 GetSimplePermissionMessages();
287 messages.insert(messages.end(), simple_msgs.begin(), simple_msgs.end());
288 273
289 return messages; 274 return messages;
290 } 275 }
291 276
292 std::vector<string16> PermissionSet::GetWarningMessages( 277 std::vector<string16> PermissionSet::GetWarningMessages(
293 Manifest::Type extension_type) const { 278 Manifest::Type extension_type) const {
294 std::vector<string16> messages; 279 std::vector<string16> messages;
295 PermissionMessages permissions = GetPermissionMessages(extension_type); 280 PermissionMessages permissions = GetPermissionMessages(extension_type);
296 281
297 bool audio_capture = false; 282 bool audio_capture = false;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 bool PermissionSet::HasEffectiveFullAccess() const { 413 bool PermissionSet::HasEffectiveFullAccess() const {
429 for (APIPermissionSet::const_iterator i = apis().begin(); 414 for (APIPermissionSet::const_iterator i = apis().begin();
430 i != apis().end(); ++i) { 415 i != apis().end(); ++i) {
431 if (i->info()->implies_full_access()) 416 if (i->info()->implies_full_access())
432 return true; 417 return true;
433 } 418 }
434 return false; 419 return false;
435 } 420 }
436 421
437 bool PermissionSet::HasLessPrivilegesThan( 422 bool PermissionSet::HasLessPrivilegesThan(
438 const PermissionSet* permissions) const { 423 const PermissionSet* permissions,
424 Manifest::Type extension_type) const {
439 // Things can't get worse than native code access. 425 // Things can't get worse than native code access.
440 if (HasEffectiveFullAccess()) 426 if (HasEffectiveFullAccess())
441 return false; 427 return false;
442 428
443 // Otherwise, it's a privilege increase if the new one has full access. 429 // Otherwise, it's a privilege increase if the new one has full access.
444 if (permissions->HasEffectiveFullAccess()) 430 if (permissions->HasEffectiveFullAccess())
445 return true; 431 return true;
446 432
447 if (HasLessHostPrivilegesThan(permissions)) 433 if (HasLessHostPrivilegesThan(permissions, extension_type))
448 return true; 434 return true;
449 435
450 if (HasLessAPIPrivilegesThan(permissions)) 436 if (HasLessAPIPrivilegesThan(permissions))
451 return true; 437 return true;
452 438
453 return false; 439 return false;
454 } 440 }
455 441
456 PermissionSet::~PermissionSet() {} 442 PermissionSet::~PermissionSet() {}
457 443
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 apis_.insert(APIPermission::kFileBrowserHandlerInternal); 516 apis_.insert(APIPermission::kFileBrowserHandlerInternal);
531 } 517 }
532 518
533 void PermissionSet::InitEffectiveHosts() { 519 void PermissionSet::InitEffectiveHosts() {
534 effective_hosts_.ClearPatterns(); 520 effective_hosts_.ClearPatterns();
535 521
536 URLPatternSet::CreateUnion( 522 URLPatternSet::CreateUnion(
537 explicit_hosts(), scriptable_hosts(), &effective_hosts_); 523 explicit_hosts(), scriptable_hosts(), &effective_hosts_);
538 } 524 }
539 525
540 std::set<PermissionMessage> 526 std::set<PermissionMessage> PermissionSet::GetAPIPermissionMessages() const {
541 PermissionSet::GetSimplePermissionMessages() const {
542 std::set<PermissionMessage> messages; 527 std::set<PermissionMessage> messages;
543 for (APIPermissionSet::const_iterator permission_it = apis_.begin(); 528 for (APIPermissionSet::const_iterator permission_it = apis_.begin();
544 permission_it != apis_.end(); ++permission_it) { 529 permission_it != apis_.end(); ++permission_it) {
545 DCHECK_GT(PermissionMessage::kNone, 530 DCHECK_GT(PermissionMessage::kNone,
546 PermissionMessage::kUnknown); 531 PermissionMessage::kUnknown);
547 if (permission_it->HasMessages()) { 532 if (permission_it->HasMessages()) {
548 PermissionMessages new_messages = permission_it->GetMessages(); 533 PermissionMessages new_messages = permission_it->GetMessages();
549 messages.insert(new_messages.begin(), new_messages.end()); 534 messages.insert(new_messages.begin(), new_messages.end());
550 } 535 }
551 } 536 }
552 return messages; 537 return messages;
553 } 538 }
554 539
540 std::set<PermissionMessage> PermissionSet::GetHostPermissionMessages(
541 Manifest::Type extension_type) const {
542 // Since platform apps always use isolated storage, they can't (silently)
543 // access user data on other domains, so there's no need to prompt.
544 // Note: this must remain consistent with HasLessHostPrivilegesThan.
545 // See crbug.com/255229.
546 std::set<PermissionMessage> messages;
547 if (extension_type == Manifest::TYPE_PLATFORM_APP)
548 return messages;
549
550 if (HasEffectiveAccessToAllHosts()) {
551 messages.insert(PermissionMessage(
552 PermissionMessage::kHostsAll,
553 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
554 } else {
555 PermissionMessages additional_warnings =
556 GetChromeSchemePermissionWarnings(effective_hosts_);
557 for (size_t i = 0; i < additional_warnings.size(); ++i)
558 messages.insert(additional_warnings[i]);
559
560 std::set<std::string> hosts = GetDistinctHostsForDisplay();
561 if (!hosts.empty())
562 messages.insert(PermissionMessage::CreateFromHostList(hosts));
563 }
564 return messages;
565 }
566
555 bool PermissionSet::HasLessAPIPrivilegesThan( 567 bool PermissionSet::HasLessAPIPrivilegesThan(
556 const PermissionSet* permissions) const { 568 const PermissionSet* permissions) const {
557 if (permissions == NULL) 569 if (permissions == NULL)
558 return false; 570 return false;
559 571
560 std::set<PermissionMessage> current_warnings = 572 std::set<PermissionMessage> current_warnings =
561 GetSimplePermissionMessages(); 573 GetAPIPermissionMessages();
562 std::set<PermissionMessage> new_warnings = 574 std::set<PermissionMessage> new_warnings =
563 permissions->GetSimplePermissionMessages(); 575 permissions->GetAPIPermissionMessages();
564 std::set<PermissionMessage> delta_warnings; 576 std::set<PermissionMessage> delta_warnings;
565 std::set_difference(new_warnings.begin(), new_warnings.end(), 577 std::set_difference(new_warnings.begin(), new_warnings.end(),
566 current_warnings.begin(), current_warnings.end(), 578 current_warnings.begin(), current_warnings.end(),
567 std::inserter(delta_warnings, delta_warnings.begin())); 579 std::inserter(delta_warnings, delta_warnings.begin()));
568 580
569 // We have less privileges if there are additional warnings present. 581 // We have less privileges if there are additional warnings present.
570 return !delta_warnings.empty(); 582 return !delta_warnings.empty();
571 } 583 }
572 584
573 bool PermissionSet::HasLessHostPrivilegesThan( 585 bool PermissionSet::HasLessHostPrivilegesThan(
574 const PermissionSet* permissions) const { 586 const PermissionSet* permissions,
587 Manifest::Type extension_type) const {
588 // Platform apps host permission changes do not count as privilege increases.
589 // Note: this must remain consistent with GetHostPermissionMessages.
590 if (extension_type == Manifest::TYPE_PLATFORM_APP)
591 return false;
592
575 // If this permission set can access any host, then it can't be elevated. 593 // If this permission set can access any host, then it can't be elevated.
576 if (HasEffectiveAccessToAllHosts()) 594 if (HasEffectiveAccessToAllHosts())
577 return false; 595 return false;
578 596
579 // Likewise, if the other permission set has full host access, then it must be 597 // Likewise, if the other permission set has full host access, then it must be
580 // a privilege increase. 598 // a privilege increase.
581 if (permissions->HasEffectiveAccessToAllHosts()) 599 if (permissions->HasEffectiveAccessToAllHosts())
582 return true; 600 return true;
583 601
584 const URLPatternSet& old_list = effective_hosts(); 602 const URLPatternSet& old_list = effective_hosts();
585 const URLPatternSet& new_list = permissions->effective_hosts(); 603 const URLPatternSet& new_list = permissions->effective_hosts();
586 604
587 // TODO(jstritar): This is overly conservative with respect to subdomains. 605 // TODO(jstritar): This is overly conservative with respect to subdomains.
588 // For example, going from *.google.com to www.google.com will be 606 // For example, going from *.google.com to www.google.com will be
589 // considered an elevation, even though it is not (http://crbug.com/65337). 607 // considered an elevation, even though it is not (http://crbug.com/65337).
590 std::set<std::string> new_hosts_set(GetDistinctHosts(new_list, false, false)); 608 std::set<std::string> new_hosts_set(GetDistinctHosts(new_list, false, false));
591 std::set<std::string> old_hosts_set(GetDistinctHosts(old_list, false, false)); 609 std::set<std::string> old_hosts_set(GetDistinctHosts(old_list, false, false));
592 std::set<std::string> new_hosts_only; 610 std::set<std::string> new_hosts_only;
593 611
594 std::set_difference(new_hosts_set.begin(), new_hosts_set.end(), 612 std::set_difference(new_hosts_set.begin(), new_hosts_set.end(),
595 old_hosts_set.begin(), old_hosts_set.end(), 613 old_hosts_set.begin(), old_hosts_set.end(),
596 std::inserter(new_hosts_only, new_hosts_only.begin())); 614 std::inserter(new_hosts_only, new_hosts_only.begin()));
597 615
598 return !new_hosts_only.empty(); 616 return !new_hosts_only.empty();
599 } 617 }
600 618
601 } // namespace extensions 619 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/permissions/permission_set.h ('k') | chrome/common/extensions/permissions/permission_set_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698