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

Side by Side Diff: chrome/common/extensions/extension.cc

Issue 12792005: Allow extensions on chrome:// URLs, when flag is set and permission is explicitly requested (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add a helper method to UserScript to get the appropriate valid schemes Created 7 years, 9 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/extension.h" 5 #include "chrome/common/extensions/extension.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes; 583 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes;
584 584
585 for (std::vector<std::string>::const_iterator it = host_data.begin(); 585 for (std::vector<std::string>::const_iterator it = host_data.begin();
586 it != host_data.end(); ++it) { 586 it != host_data.end(); ++it) {
587 const std::string& permission_str = *it; 587 const std::string& permission_str = *it;
588 588
589 // Check if it's a host pattern permission. 589 // Check if it's a host pattern permission.
590 URLPattern pattern = URLPattern(kAllowedSchemes); 590 URLPattern pattern = URLPattern(kAllowedSchemes);
591 URLPattern::ParseResult parse_result = pattern.Parse(permission_str); 591 URLPattern::ParseResult parse_result = pattern.Parse(permission_str);
592 if (parse_result == URLPattern::PARSE_SUCCESS) { 592 if (parse_result == URLPattern::PARSE_SUCCESS) {
593 // The path component is not used for host permissions, so we force it
594 // to match all paths.
595 pattern.SetPath("/*");
596 int valid_schemes = pattern.valid_schemes();
597 if (pattern.MatchesScheme(chrome::kFileScheme) &&
598 !CanExecuteScriptEverywhere()) {
599 wants_file_access_ = true;
600 if (!(creation_flags_ & ALLOW_FILE_ACCESS))
601 valid_schemes &= ~URLPattern::SCHEME_FILE;
602 }
603
604 if (pattern.scheme() != chrome::kChromeUIScheme &&
605 !CanExecuteScriptEverywhere()) {
606 // Keep chrome:// in allowed schemes only if it's explicitly requested
607 // or CanExecuteScriptEverywhere is true. If the
608 // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission
609 // will fail, so don't check the flag here.
610 valid_schemes &= ~URLPattern::SCHEME_CHROMEUI;
611 }
612 pattern.SetValidSchemes(valid_schemes);
613
593 if (!CanSpecifyHostPermission(pattern, *api_permissions)) { 614 if (!CanSpecifyHostPermission(pattern, *api_permissions)) {
615 // TODO(aboxhall): make a warning (see line 633)
594 *error = ErrorUtils::FormatErrorMessageUTF16( 616 *error = ErrorUtils::FormatErrorMessageUTF16(
595 errors::kInvalidPermissionScheme, permission_str); 617 errors::kInvalidPermissionScheme, permission_str);
596 return false; 618 return false;
597 } 619 }
598 620
599 // The path component is not used for host permissions, so we force it 621 host_permissions->AddPattern(pattern);
600 // to match all paths.
601 pattern.SetPath("/*");
602 622
603 if (pattern.MatchesScheme(chrome::kFileScheme) && 623 // We need to make sure all_urls matches chrome://favicon and
604 !CanExecuteScriptEverywhere()) { 624 // (maybe) chrome://thumbnail, so add them back in to host_permissions
605 wants_file_access_ = true; 625 // separately.
606 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { 626 if (pattern.match_all_urls()) {
607 pattern.SetValidSchemes( 627 host_permissions->AddPattern(
608 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); 628 URLPattern(URLPattern::SCHEME_CHROMEUI,
629 chrome::kChromeUIFaviconURL));
630 if (api_permissions->find(APIPermission::kExperimental) !=
631 api_permissions->end()) {
632 host_permissions->AddPattern(
633 URLPattern(URLPattern::SCHEME_CHROMEUI,
634 chrome::kChromeUIThumbnailURL));
609 } 635 }
610 } 636 }
611
612 host_permissions->AddPattern(pattern);
613 continue; 637 continue;
614 } 638 }
615 639
616 // It's probably an unknown API permission. Do not throw an error so 640 // It's probably an unknown API permission. Do not throw an error so
617 // extensions can retain backwards compatability (http://crbug.com/42742). 641 // extensions can retain backwards compatability (http://crbug.com/42742).
618 install_warnings_.push_back(InstallWarning( 642 install_warnings_.push_back(InstallWarning(
619 InstallWarning::FORMAT_TEXT, 643 InstallWarning::FORMAT_TEXT,
620 base::StringPrintf( 644 base::StringPrintf(
621 "Permission '%s' is unknown or URL pattern is malformed.", 645 "Permission '%s' is unknown or URL pattern is malformed.",
622 permission_str.c_str()))); 646 permission_str.c_str())));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 const URLPatternSet& Extension::GetEffectiveHostPermissions() const { 681 const URLPatternSet& Extension::GetEffectiveHostPermissions() const {
658 base::AutoLock auto_lock(runtime_data_lock_); 682 base::AutoLock auto_lock(runtime_data_lock_);
659 return runtime_data_.GetActivePermissions()->effective_hosts(); 683 return runtime_data_.GetActivePermissions()->effective_hosts();
660 } 684 }
661 685
662 bool Extension::CanSilentlyIncreasePermissions() const { 686 bool Extension::CanSilentlyIncreasePermissions() const {
663 return location() != Manifest::INTERNAL; 687 return location() != Manifest::INTERNAL;
664 } 688 }
665 689
666 bool Extension::HasHostPermission(const GURL& url) const { 690 bool Extension::HasHostPermission(const GURL& url) const {
667 if (url.SchemeIs(chrome::kChromeUIScheme) &&
668 url.host() != chrome::kChromeUIFaviconHost &&
669 url.host() != chrome::kChromeUIThumbnailHost &&
670 location() != Manifest::COMPONENT) {
671 return false;
672 }
673
674 base::AutoLock auto_lock(runtime_data_lock_); 691 base::AutoLock auto_lock(runtime_data_lock_);
675 return runtime_data_.GetActivePermissions()-> 692 return runtime_data_.GetActivePermissions()->
676 HasExplicitAccessToOrigin(url); 693 HasExplicitAccessToOrigin(url);
677 } 694 }
678 695
679 bool Extension::HasEffectiveAccessToAllHosts() const { 696 bool Extension::HasEffectiveAccessToAllHosts() const {
680 base::AutoLock auto_lock(runtime_data_lock_); 697 base::AutoLock auto_lock(runtime_data_lock_);
681 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts(); 698 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts();
682 } 699 }
683 700
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 GURL store_url(extension_urls::GetWebstoreLaunchURL()); 813 GURL store_url(extension_urls::GetWebstoreLaunchURL());
797 if ((document_url.host() == store_url.host()) && 814 if ((document_url.host() == store_url.host()) &&
798 !CanExecuteScriptEverywhere() && 815 !CanExecuteScriptEverywhere() &&
799 !CommandLine::ForCurrentProcess()->HasSwitch( 816 !CommandLine::ForCurrentProcess()->HasSwitch(
800 switches::kAllowScriptingGallery)) { 817 switches::kAllowScriptingGallery)) {
801 if (error) 818 if (error)
802 *error = errors::kCannotScriptGallery; 819 *error = errors::kCannotScriptGallery;
803 return false; 820 return false;
804 } 821 }
805 822
806 if (document_url.SchemeIs(chrome::kChromeUIScheme) && 823 if (!CommandLine::ForCurrentProcess()->HasSwitch(
807 !CanExecuteScriptEverywhere()) { 824 switches::kExtensionsOnChromeURLs)) {
808 return false; 825 if (document_url.SchemeIs(chrome::kChromeUIScheme) &&
826 !CanExecuteScriptEverywhere()) {
827 return false;
dmazzoni 2013/03/19 20:48:44 Doesn't this allow any extension to run on chrome:
aboxhall 2013/03/20 22:04:59 It's caught later, specifically on either line 850
828 }
809 } 829 }
810 830
811 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && 831 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) &&
812 top_frame_url.GetOrigin() != 832 top_frame_url.GetOrigin() !=
813 GetBaseURLFromExtensionId(id()).GetOrigin() && 833 GetBaseURLFromExtensionId(id()).GetOrigin() &&
814 !CanExecuteScriptEverywhere()) { 834 !CanExecuteScriptEverywhere()) {
815 return false; 835 return false;
816 } 836 }
817 837
818 // If a tab ID is specified, try the tab-specific permissions. 838 // If a tab ID is specified, try the tab-specific permissions.
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 std::string match_str; 2168 std::string match_str;
2149 if (!matches->GetString(j, &match_str)) { 2169 if (!matches->GetString(j, &match_str)) {
2150 *error = ErrorUtils::FormatErrorMessageUTF16( 2170 *error = ErrorUtils::FormatErrorMessageUTF16(
2151 errors::kInvalidMatch, 2171 errors::kInvalidMatch,
2152 base::IntToString(definition_index), 2172 base::IntToString(definition_index),
2153 base::IntToString(j), 2173 base::IntToString(j),
2154 errors::kExpectString); 2174 errors::kExpectString);
2155 return false; 2175 return false;
2156 } 2176 }
2157 2177
2158 URLPattern pattern(UserScript::kValidUserScriptSchemes); 2178 URLPattern pattern(
2159 if (CanExecuteScriptEverywhere()) 2179 UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere()));
2160 pattern.SetValidSchemes(URLPattern::SCHEME_ALL);
2161 2180
2162 URLPattern::ParseResult parse_result = pattern.Parse(match_str); 2181 URLPattern::ParseResult parse_result = pattern.Parse(match_str);
2163 if (parse_result != URLPattern::PARSE_SUCCESS) { 2182 if (parse_result != URLPattern::PARSE_SUCCESS) {
2164 *error = ErrorUtils::FormatErrorMessageUTF16( 2183 *error = ErrorUtils::FormatErrorMessageUTF16(
2165 errors::kInvalidMatch, 2184 errors::kInvalidMatch,
2166 base::IntToString(definition_index), 2185 base::IntToString(definition_index),
2167 base::IntToString(j), 2186 base::IntToString(j),
2168 URLPattern::GetParseResultString(parse_result)); 2187 URLPattern::GetParseResultString(parse_result));
2169 return false; 2188 return false;
2170 } 2189 }
2171 2190
2191 // TODO(aboxhall): check for webstore
2192 if (!CanExecuteScriptEverywhere() &&
2193 pattern.scheme() != chrome::kChromeUIScheme) {
2194 pattern.SetValidSchemes(
Matt Perry 2013/03/19 17:49:32 Add a comment on what's happening here.
aboxhall 2013/03/20 22:04:59 Done.
aboxhall 2013/03/20 22:04:59 Done.
2195 pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI);
2196 }
2197
2172 if (pattern.MatchesScheme(chrome::kFileScheme) && 2198 if (pattern.MatchesScheme(chrome::kFileScheme) &&
2173 !CanExecuteScriptEverywhere()) { 2199 !CanExecuteScriptEverywhere()) {
2174 wants_file_access_ = true; 2200 wants_file_access_ = true;
2175 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { 2201 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) {
2176 pattern.SetValidSchemes( 2202 pattern.SetValidSchemes(
2177 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); 2203 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
2178 } 2204 }
2179 } 2205 }
2180 2206
2181 result->add_url_pattern(pattern); 2207 result->add_url_pattern(pattern);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 // Experimental extensions are also allowed chrome://thumb. 2427 // Experimental extensions are also allowed chrome://thumb.
2402 if (pattern.host() == chrome::kChromeUIThumbnailHost) { 2428 if (pattern.host() == chrome::kChromeUIThumbnailHost) {
2403 return permissions.find(APIPermission::kExperimental) != 2429 return permissions.find(APIPermission::kExperimental) !=
2404 permissions.end(); 2430 permissions.end();
2405 } 2431 }
2406 2432
2407 // Component extensions can have access to all of chrome://*. 2433 // Component extensions can have access to all of chrome://*.
2408 if (CanExecuteScriptEverywhere()) 2434 if (CanExecuteScriptEverywhere())
2409 return true; 2435 return true;
2410 2436
2437 if (CommandLine::ForCurrentProcess()->HasSwitch(
2438 switches::kExtensionsOnChromeURLs))
2439 return true;
2440
2441 // TODO(aboxhall): return from_webstore() when webstore handles blocking
2442 // extensions which request chrome:// urls
2411 return false; 2443 return false;
2412 } 2444 }
2413 2445
2414 // Otherwise, the valid schemes were handled by URLPattern. 2446 // Otherwise, the valid schemes were handled by URLPattern.
2415 return true; 2447 return true;
2416 } 2448 }
2417 2449
2418 bool Extension::CheckMinimumChromeVersion(string16* error) const { 2450 bool Extension::CheckMinimumChromeVersion(string16* error) const {
2419 if (!manifest_->HasKey(keys::kMinimumChromeVersion)) 2451 if (!manifest_->HasKey(keys::kMinimumChromeVersion))
2420 return true; 2452 return true;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2502 2534
2503 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 2535 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
2504 const Extension* extension, 2536 const Extension* extension,
2505 const PermissionSet* permissions, 2537 const PermissionSet* permissions,
2506 Reason reason) 2538 Reason reason)
2507 : reason(reason), 2539 : reason(reason),
2508 extension(extension), 2540 extension(extension),
2509 permissions(permissions) {} 2541 permissions(permissions) {}
2510 2542
2511 } // namespace extensions 2543 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698