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

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: Reinstate original pickle order; add scripts clause to content_script_chrome_url_invalid.json to av… 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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 #endif 210 #endif
211 211
212 // first 16 bytes of SHA256 hashed public key. 212 // first 16 bytes of SHA256 hashed public key.
213 const size_t Extension::kIdSize = 16; 213 const size_t Extension::kIdSize = 16;
214 214
215 const char Extension::kMimeType[] = "application/x-chrome-extension"; 215 const char Extension::kMimeType[] = "application/x-chrome-extension";
216 216
217 const int Extension::kValidWebExtentSchemes = 217 const int Extension::kValidWebExtentSchemes =
218 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; 218 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS;
219 219
220 const int Extension::kValidHostPermissionSchemes = 220 const int Extension::kValidHostPermissionSchemes = URLPattern::SCHEME_CHROMEUI |
221 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; 221 URLPattern::SCHEME_HTTP |
222 URLPattern::SCHEME_HTTPS |
223 URLPattern::SCHEME_FILE |
224 URLPattern::SCHEME_FTP;
222 225
223 Extension::Requirements::Requirements() 226 Extension::Requirements::Requirements()
224 : webgl(false), 227 : webgl(false),
225 css3d(false), 228 css3d(false),
226 npapi(false) { 229 npapi(false) {
227 } 230 }
228 231
229 Extension::Requirements::~Requirements() {} 232 Extension::Requirements::~Requirements() {}
230 233
231 // 234 //
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes; 586 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes;
584 587
585 for (std::vector<std::string>::const_iterator it = host_data.begin(); 588 for (std::vector<std::string>::const_iterator it = host_data.begin();
586 it != host_data.end(); ++it) { 589 it != host_data.end(); ++it) {
587 const std::string& permission_str = *it; 590 const std::string& permission_str = *it;
588 591
589 // Check if it's a host pattern permission. 592 // Check if it's a host pattern permission.
590 URLPattern pattern = URLPattern(kAllowedSchemes); 593 URLPattern pattern = URLPattern(kAllowedSchemes);
591 URLPattern::ParseResult parse_result = pattern.Parse(permission_str); 594 URLPattern::ParseResult parse_result = pattern.Parse(permission_str);
592 if (parse_result == URLPattern::PARSE_SUCCESS) { 595 if (parse_result == URLPattern::PARSE_SUCCESS) {
596 // The path component is not used for host permissions, so we force it
597 // to match all paths.
598 pattern.SetPath("/*");
599 int valid_schemes = pattern.valid_schemes();
600 if (pattern.MatchesScheme(chrome::kFileScheme) &&
601 !CanExecuteScriptEverywhere()) {
602 wants_file_access_ = true;
603 if (!(creation_flags_ & ALLOW_FILE_ACCESS))
604 valid_schemes &= ~URLPattern::SCHEME_FILE;
605 }
606
607 if (pattern.scheme() != chrome::kChromeUIScheme &&
608 !CanExecuteScriptEverywhere()) {
609 // Keep chrome:// in allowed schemes only if it's explicitly requested
610 // or CanExecuteScriptEverywhere is true. If the
611 // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission
612 // will fail, so don't check the flag here.
613 valid_schemes &= ~URLPattern::SCHEME_CHROMEUI;
614 }
615 pattern.SetValidSchemes(valid_schemes);
616
593 if (!CanSpecifyHostPermission(pattern, *api_permissions)) { 617 if (!CanSpecifyHostPermission(pattern, *api_permissions)) {
618 // TODO(aboxhall): make a warning (see line 633)
594 *error = ErrorUtils::FormatErrorMessageUTF16( 619 *error = ErrorUtils::FormatErrorMessageUTF16(
595 errors::kInvalidPermissionScheme, permission_str); 620 errors::kInvalidPermissionScheme, permission_str);
596 return false; 621 return false;
597 } 622 }
598 623
599 // The path component is not used for host permissions, so we force it 624 host_permissions->AddPattern(pattern);
600 // to match all paths.
601 pattern.SetPath("/*");
602 625
603 if (pattern.MatchesScheme(chrome::kFileScheme) && 626 // We need to make sure all_urls matches chrome://favicon and
604 !CanExecuteScriptEverywhere()) { 627 // (maybe) chrome://thumbnail, so add them back in to host_permissions
605 wants_file_access_ = true; 628 // separately.
606 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { 629 if (pattern.match_all_urls()) {
607 pattern.SetValidSchemes( 630 host_permissions->AddPattern(
608 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); 631 URLPattern(URLPattern::SCHEME_CHROMEUI,
632 chrome::kChromeUIFaviconURL));
633 if (api_permissions->find(APIPermission::kExperimental) !=
634 api_permissions->end()) {
635 host_permissions->AddPattern(
636 URLPattern(URLPattern::SCHEME_CHROMEUI,
637 chrome::kChromeUIThumbnailURL));
609 } 638 }
610 } 639 }
611
612 host_permissions->AddPattern(pattern);
613 continue; 640 continue;
614 } 641 }
615 642
616 // It's probably an unknown API permission. Do not throw an error so 643 // It's probably an unknown API permission. Do not throw an error so
617 // extensions can retain backwards compatability (http://crbug.com/42742). 644 // extensions can retain backwards compatability (http://crbug.com/42742).
618 install_warnings_.push_back(InstallWarning( 645 install_warnings_.push_back(InstallWarning(
619 InstallWarning::FORMAT_TEXT, 646 InstallWarning::FORMAT_TEXT,
620 base::StringPrintf( 647 base::StringPrintf(
621 "Permission '%s' is unknown or URL pattern is malformed.", 648 "Permission '%s' is unknown or URL pattern is malformed.",
622 permission_str.c_str()))); 649 permission_str.c_str())));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 const URLPatternSet& Extension::GetEffectiveHostPermissions() const { 684 const URLPatternSet& Extension::GetEffectiveHostPermissions() const {
658 base::AutoLock auto_lock(runtime_data_lock_); 685 base::AutoLock auto_lock(runtime_data_lock_);
659 return runtime_data_.GetActivePermissions()->effective_hosts(); 686 return runtime_data_.GetActivePermissions()->effective_hosts();
660 } 687 }
661 688
662 bool Extension::CanSilentlyIncreasePermissions() const { 689 bool Extension::CanSilentlyIncreasePermissions() const {
663 return location() != Manifest::INTERNAL; 690 return location() != Manifest::INTERNAL;
664 } 691 }
665 692
666 bool Extension::HasHostPermission(const GURL& url) const { 693 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_); 694 base::AutoLock auto_lock(runtime_data_lock_);
675 return runtime_data_.GetActivePermissions()-> 695 return runtime_data_.GetActivePermissions()->
676 HasExplicitAccessToOrigin(url); 696 HasExplicitAccessToOrigin(url);
677 } 697 }
678 698
679 bool Extension::HasEffectiveAccessToAllHosts() const { 699 bool Extension::HasEffectiveAccessToAllHosts() const {
680 base::AutoLock auto_lock(runtime_data_lock_); 700 base::AutoLock auto_lock(runtime_data_lock_);
681 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts(); 701 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts();
682 } 702 }
683 703
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 GURL store_url(extension_urls::GetWebstoreLaunchURL()); 816 GURL store_url(extension_urls::GetWebstoreLaunchURL());
797 if ((document_url.host() == store_url.host()) && 817 if ((document_url.host() == store_url.host()) &&
798 !CanExecuteScriptEverywhere() && 818 !CanExecuteScriptEverywhere() &&
799 !CommandLine::ForCurrentProcess()->HasSwitch( 819 !CommandLine::ForCurrentProcess()->HasSwitch(
800 switches::kAllowScriptingGallery)) { 820 switches::kAllowScriptingGallery)) {
801 if (error) 821 if (error)
802 *error = errors::kCannotScriptGallery; 822 *error = errors::kCannotScriptGallery;
803 return false; 823 return false;
804 } 824 }
805 825
806 if (document_url.SchemeIs(chrome::kChromeUIScheme) && 826 if (!CommandLine::ForCurrentProcess()->HasSwitch(
807 !CanExecuteScriptEverywhere()) { 827 switches::kExtensionsOnChromeURLs)) {
808 return false; 828 if (document_url.SchemeIs(chrome::kChromeUIScheme) &&
829 !CanExecuteScriptEverywhere()) {
830 return false;
831 }
809 } 832 }
810 833
811 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && 834 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) &&
812 top_frame_url.GetOrigin() != 835 top_frame_url.GetOrigin() !=
813 GetBaseURLFromExtensionId(id()).GetOrigin() && 836 GetBaseURLFromExtensionId(id()).GetOrigin() &&
814 !CanExecuteScriptEverywhere()) { 837 !CanExecuteScriptEverywhere()) {
815 return false; 838 return false;
816 } 839 }
817 840
818 // If a tab ID is specified, try the tab-specific permissions. 841 // If a tab ID is specified, try the tab-specific permissions.
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 !LoadSystemIndicator(error) || 1978 !LoadSystemIndicator(error) ||
1956 !LoadIncognitoMode(error)) 1979 !LoadIncognitoMode(error))
1957 return false; 1980 return false;
1958 1981
1959 return true; 1982 return true;
1960 } 1983 }
1961 1984
1962 bool Extension::LoadContentScripts(string16* error) { 1985 bool Extension::LoadContentScripts(string16* error) {
1963 if (!manifest_->HasKey(keys::kContentScripts)) 1986 if (!manifest_->HasKey(keys::kContentScripts))
1964 return true; 1987 return true;
1988
1965 const ListValue* list_value; 1989 const ListValue* list_value;
1966 if (!manifest_->GetList(keys::kContentScripts, &list_value)) { 1990 if (!manifest_->GetList(keys::kContentScripts, &list_value)) {
1967 *error = ASCIIToUTF16(errors::kInvalidContentScriptsList); 1991 *error = ASCIIToUTF16(errors::kInvalidContentScriptsList);
1968 return false; 1992 return false;
1969 } 1993 }
1970 1994
1971 for (size_t i = 0; i < list_value->GetSize(); ++i) { 1995 for (size_t i = 0; i < list_value->GetSize(); ++i) {
1972 const DictionaryValue* content_script = NULL; 1996 const DictionaryValue* content_script = NULL;
1973 if (!list_value->GetDictionary(i, &content_script)) { 1997 if (!list_value->GetDictionary(i, &content_script)) {
1974 *error = ErrorUtils::FormatErrorMessageUTF16( 1998 *error = ErrorUtils::FormatErrorMessageUTF16(
1975 errors::kInvalidContentScript, base::IntToString(i)); 1999 errors::kInvalidContentScript, base::IntToString(i));
1976 return false; 2000 return false;
1977 } 2001 }
1978 2002
1979 UserScript script; 2003 UserScript script;
1980 if (!LoadUserScriptHelper(content_script, i, error, &script)) 2004 if (!LoadUserScriptHelper(content_script, i, error, &script))
1981 return false; // Failed to parse script context definition. 2005 return false; // Failed to parse script context definition.
2006
1982 script.set_extension_id(id()); 2007 script.set_extension_id(id());
1983 if (converted_from_user_script_) { 2008 if (converted_from_user_script_) {
1984 script.set_emulate_greasemonkey(true); 2009 script.set_emulate_greasemonkey(true);
1985 script.set_match_all_frames(true); // Greasemonkey matches all frames. 2010 script.set_match_all_frames(true); // Greasemonkey matches all frames.
1986 } 2011 }
1987 content_scripts_.push_back(script); 2012 content_scripts_.push_back(script);
1988 } 2013 }
1989 return true; 2014 return true;
1990 } 2015 }
1991 2016
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2097 std::string match_str; 2122 std::string match_str;
2098 if (!matches->GetString(j, &match_str)) { 2123 if (!matches->GetString(j, &match_str)) {
2099 *error = ErrorUtils::FormatErrorMessageUTF16( 2124 *error = ErrorUtils::FormatErrorMessageUTF16(
2100 errors::kInvalidMatch, 2125 errors::kInvalidMatch,
2101 base::IntToString(definition_index), 2126 base::IntToString(definition_index),
2102 base::IntToString(j), 2127 base::IntToString(j),
2103 errors::kExpectString); 2128 errors::kExpectString);
2104 return false; 2129 return false;
2105 } 2130 }
2106 2131
2107 URLPattern pattern(UserScript::kValidUserScriptSchemes); 2132 URLPattern pattern(
2108 if (CanExecuteScriptEverywhere()) 2133 UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere()));
2109 pattern.SetValidSchemes(URLPattern::SCHEME_ALL);
2110 2134
2111 URLPattern::ParseResult parse_result = pattern.Parse(match_str); 2135 URLPattern::ParseResult parse_result = pattern.Parse(match_str);
2112 if (parse_result != URLPattern::PARSE_SUCCESS) { 2136 if (parse_result != URLPattern::PARSE_SUCCESS) {
2113 *error = ErrorUtils::FormatErrorMessageUTF16( 2137 *error = ErrorUtils::FormatErrorMessageUTF16(
2114 errors::kInvalidMatch, 2138 errors::kInvalidMatch,
2115 base::IntToString(definition_index), 2139 base::IntToString(definition_index),
2116 base::IntToString(j), 2140 base::IntToString(j),
2117 URLPattern::GetParseResultString(parse_result)); 2141 URLPattern::GetParseResultString(parse_result));
2118 return false; 2142 return false;
2119 } 2143 }
2120 2144
2145 // TODO(aboxhall): check for webstore
2146 if (!CanExecuteScriptEverywhere() &&
2147 pattern.scheme() != chrome::kChromeUIScheme) {
2148 // Exclude SCHEME_CHROMEUI unless it's been explicitly requested.
2149 // If the --extensions-on-chrome-urls flag has not been passed, requesting
2150 // a chrome:// url will cause a parse failure above, so there's no need to
2151 // check the flag here.
2152 pattern.SetValidSchemes(
2153 pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI);
2154 }
2155
2121 if (pattern.MatchesScheme(chrome::kFileScheme) && 2156 if (pattern.MatchesScheme(chrome::kFileScheme) &&
2122 !CanExecuteScriptEverywhere()) { 2157 !CanExecuteScriptEverywhere()) {
2123 wants_file_access_ = true; 2158 wants_file_access_ = true;
2124 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { 2159 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) {
2125 pattern.SetValidSchemes( 2160 pattern.SetValidSchemes(
2126 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); 2161 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
2127 } 2162 }
2128 } 2163 }
2129 2164
2130 result->add_url_pattern(pattern); 2165 result->add_url_pattern(pattern);
(...skipping 13 matching lines...) Expand all
2144 std::string match_str; 2179 std::string match_str;
2145 if (!exclude_matches->GetString(j, &match_str)) { 2180 if (!exclude_matches->GetString(j, &match_str)) {
2146 *error = ErrorUtils::FormatErrorMessageUTF16( 2181 *error = ErrorUtils::FormatErrorMessageUTF16(
2147 errors::kInvalidExcludeMatch, 2182 errors::kInvalidExcludeMatch,
2148 base::IntToString(definition_index), 2183 base::IntToString(definition_index),
2149 base::IntToString(j), 2184 base::IntToString(j),
2150 errors::kExpectString); 2185 errors::kExpectString);
2151 return false; 2186 return false;
2152 } 2187 }
2153 2188
2154 URLPattern pattern(UserScript::kValidUserScriptSchemes); 2189 int valid_schemes =
2155 if (CanExecuteScriptEverywhere()) 2190 UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere());
2156 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); 2191 URLPattern pattern(valid_schemes);
2157 URLPattern::ParseResult parse_result = pattern.Parse(match_str); 2192 URLPattern::ParseResult parse_result = pattern.Parse(match_str);
2158 if (parse_result != URLPattern::PARSE_SUCCESS) { 2193 if (parse_result != URLPattern::PARSE_SUCCESS) {
2159 *error = ErrorUtils::FormatErrorMessageUTF16( 2194 *error = ErrorUtils::FormatErrorMessageUTF16(
2160 errors::kInvalidExcludeMatch, 2195 errors::kInvalidExcludeMatch,
2161 base::IntToString(definition_index), base::IntToString(j), 2196 base::IntToString(definition_index), base::IntToString(j),
2162 URLPattern::GetParseResultString(parse_result)); 2197 URLPattern::GetParseResultString(parse_result));
2163 return false; 2198 return false;
2164 } 2199 }
2165 2200
2166 result->add_exclude_url_pattern(pattern); 2201 result->add_exclude_url_pattern(pattern);
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 // Experimental extensions are also allowed chrome://thumb. 2385 // Experimental extensions are also allowed chrome://thumb.
2351 if (pattern.host() == chrome::kChromeUIThumbnailHost) { 2386 if (pattern.host() == chrome::kChromeUIThumbnailHost) {
2352 return permissions.find(APIPermission::kExperimental) != 2387 return permissions.find(APIPermission::kExperimental) !=
2353 permissions.end(); 2388 permissions.end();
2354 } 2389 }
2355 2390
2356 // Component extensions can have access to all of chrome://*. 2391 // Component extensions can have access to all of chrome://*.
2357 if (CanExecuteScriptEverywhere()) 2392 if (CanExecuteScriptEverywhere())
2358 return true; 2393 return true;
2359 2394
2395 if (CommandLine::ForCurrentProcess()->HasSwitch(
2396 switches::kExtensionsOnChromeURLs))
2397 return true;
2398
2399 // TODO(aboxhall): return from_webstore() when webstore handles blocking
2400 // extensions which request chrome:// urls
2360 return false; 2401 return false;
2361 } 2402 }
2362 2403
2363 // Otherwise, the valid schemes were handled by URLPattern. 2404 // Otherwise, the valid schemes were handled by URLPattern.
2364 return true; 2405 return true;
2365 } 2406 }
2366 2407
2367 bool Extension::CheckMinimumChromeVersion(string16* error) const { 2408 bool Extension::CheckMinimumChromeVersion(string16* error) const {
2368 if (!manifest_->HasKey(keys::kMinimumChromeVersion)) 2409 if (!manifest_->HasKey(keys::kMinimumChromeVersion))
2369 return true; 2410 return true;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 2492
2452 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 2493 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
2453 const Extension* extension, 2494 const Extension* extension,
2454 const PermissionSet* permissions, 2495 const PermissionSet* permissions,
2455 Reason reason) 2496 Reason reason)
2456 : reason(reason), 2497 : reason(reason),
2457 extension(extension), 2498 extension(extension),
2458 permissions(permissions) {} 2499 permissions(permissions) {}
2459 2500
2460 } // namespace extensions 2501 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/api/extension_api.cc ('k') | chrome/common/extensions/extension_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698