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 3 // found in the LICENSE file. 4 5 #include <vector> 6 7 #include "base/command_line.h" 8 #include "base/memory/ref_counted.h" 9 #include "base/strings/string16.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "chrome/common/chrome_version_info.h" 12 #include "chrome/common/extensions/extension_test_util.h" 13 #include "chrome/common/extensions/features/feature_channel.h" 14 #include "content/public/common/socket_permission_request.h" 15 #include "extensions/common/error_utils.h" 16 #include "extensions/common/extension.h" 17 #include "extensions/common/extension_builder.h" 18 #include "extensions/common/id_util.h" 19 #include "extensions/common/manifest.h" 20 #include "extensions/common/manifest_constants.h" 21 #include "extensions/common/permissions/api_permission.h" 22 #include "extensions/common/permissions/permission_set.h" 23 #include "extensions/common/permissions/permissions_data.h" 24 #include "extensions/common/permissions/socket_permission.h" 25 #include "extensions/common/switches.h" 26 #include "extensions/common/url_pattern_set.h" 27 #include "extensions/common/value_builder.h" 28 #include "testing/gtest/include/gtest/gtest.h" 29 #include "url/gurl.h" 30 31 using base::UTF16ToUTF8; 32 using content::SocketPermissionRequest; 33 using extension_test_util::LoadManifest; 34 using extension_test_util::LoadManifestUnchecked; 35 using extension_test_util::LoadManifestStrict; 36 37 namespace extensions { 38 39 namespace { 40 41 const char kAllHostsPermission[] = "*://*/*"; 42 43 bool CheckSocketPermission( 44 scoped_refptr<Extension> extension, 45 SocketPermissionRequest::OperationType type, 46 const char* host, 47 int port) { 48 SocketPermission::CheckParam param(type, host, port); 49 return extension->permissions_data()->CheckAPIPermissionWithParam( 50 APIPermission::kSocket, ¶m); 51 } 52 53 // Creates and returns an extension with the given |id|, |host_permissions|, and 54 // manifest |location|. 55 scoped_refptr<const Extension> GetExtensionWithHostPermission( 56 const std::string& id, 57 const std::string& host_permissions, 58 Manifest::Location location) { 59 ListBuilder permissions; 60 if (!host_permissions.empty()) 61 permissions.Append(host_permissions); 62 63 return ExtensionBuilder() 64 .SetManifest( 65 DictionaryBuilder() 66 .Set("name", id) 67 .Set("description", "an extension") 68 .Set("manifest_version", 2) 69 .Set("version", "1.0.0") 70 .Set("permissions", permissions.Pass()) 71 .Build()) 72 .SetLocation(location) 73 .SetID(id) 74 .Build(); 75 } 76 77 bool RequiresActionForScriptExecution(const std::string& extension_id, 78 const std::string& host_permissions, 79 Manifest::Location location) { 80 scoped_refptr<const Extension> extension = 81 GetExtensionWithHostPermission(extension_id, 82 host_permissions, 83 location); 84 return extension->permissions_data()->RequiresActionForScriptExecution( 85 extension, 86 -1, // Ignore tab id for these. 87 GURL::EmptyGURL()); 88 } 89 90 // Checks that urls are properly restricted for the given extension. 91 void CheckRestrictedUrls(const Extension* extension, 92 bool block_chrome_urls) { 93 // We log the name so we know _which_ extension failed here. 94 const std::string& name = extension->name(); 95 const GURL chrome_settings_url("chrome://settings/"); 96 const GURL chrome_extension_url("chrome-extension://foo/bar.html"); 97 const GURL google_url("https://www.google.com/"); 98 const GURL self_url("chrome-extension://" + extension->id() + "/foo.html"); 99 const GURL invalid_url("chrome-debugger://foo/bar.html"); 100 101 std::string error; 102 EXPECT_EQ(block_chrome_urls, 103 PermissionsData::IsRestrictedUrl( 104 chrome_settings_url, 105 chrome_settings_url, 106 extension, 107 &error)) << name; 108 if (block_chrome_urls) 109 EXPECT_EQ(manifest_errors::kCannotAccessChromeUrl, error) << name; 110 else 111 EXPECT_TRUE(error.empty()) << name; 112 113 error.clear(); 114 EXPECT_EQ(block_chrome_urls, 115 PermissionsData::IsRestrictedUrl( 116 chrome_extension_url, 117 chrome_extension_url, 118 extension, 119 &error)) << name; 120 if (block_chrome_urls) 121 EXPECT_EQ(manifest_errors::kCannotAccessExtensionUrl, error) << name; 122 else 123 EXPECT_TRUE(error.empty()) << name; 124 125 // Google should never be a restricted url. 126 error.clear(); 127 EXPECT_FALSE(PermissionsData::IsRestrictedUrl( 128 google_url, google_url, extension, &error)) << name; 129 EXPECT_TRUE(error.empty()) << name; 130 131 // We should always be able to access our own extension pages. 132 error.clear(); 133 EXPECT_FALSE(PermissionsData::IsRestrictedUrl( 134 self_url, self_url, extension, &error)) << name; 135 EXPECT_TRUE(error.empty()) << name; 136 137 // We should only allow other schemes for extensions when it's a whitelisted 138 // extension. 139 error.clear(); 140 bool allow_on_other_schemes = 141 PermissionsData::CanExecuteScriptEverywhere(extension); 142 EXPECT_EQ(!allow_on_other_schemes, 143 PermissionsData::IsRestrictedUrl( 144 invalid_url, invalid_url, extension, &error)) << name; 145 if (!allow_on_other_schemes) { 146 EXPECT_EQ(ErrorUtils::FormatErrorMessage( 147 manifest_errors::kCannotAccessPage, 148 invalid_url.spec()), 149 error) << name; 150 } else { 151 EXPECT_TRUE(error.empty()); 152 } 153 } 154 155 } // namespace 156 157 TEST(ExtensionPermissionsTest, EffectiveHostPermissions) { 158 scoped_refptr<Extension> extension; 159 URLPatternSet hosts; 160 161 extension = LoadManifest("effective_host_permissions", "empty.json"); 162 EXPECT_EQ(0u, 163 extension->permissions_data() 164 ->GetEffectiveHostPermissions() 165 .patterns() 166 .size()); 167 EXPECT_FALSE(hosts.MatchesURL(GURL("http://www.google.com"))); 168 EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 169 170 extension = LoadManifest("effective_host_permissions", "one_host.json"); 171 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 172 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 173 EXPECT_FALSE(hosts.MatchesURL(GURL("https://www.google.com"))); 174 EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 175 176 extension = LoadManifest("effective_host_permissions", 177 "one_host_wildcard.json"); 178 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 179 EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com"))); 180 EXPECT_TRUE(hosts.MatchesURL(GURL("http://foo.google.com"))); 181 EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 182 183 extension = LoadManifest("effective_host_permissions", "two_hosts.json"); 184 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 185 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 186 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com"))); 187 EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 188 189 extension = LoadManifest("effective_host_permissions", 190 "https_not_considered.json"); 191 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 192 EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com"))); 193 EXPECT_TRUE(hosts.MatchesURL(GURL("https://google.com"))); 194 EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 195 196 extension = LoadManifest("effective_host_permissions", 197 "two_content_scripts.json"); 198 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 199 EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com"))); 200 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com"))); 201 EXPECT_TRUE(extension->permissions_data() 202 ->active_permissions() 203 ->HasEffectiveAccessToURL(GURL("http://www.reddit.com"))); 204 EXPECT_TRUE(hosts.MatchesURL(GURL("http://news.ycombinator.com"))); 205 EXPECT_TRUE( 206 extension->permissions_data() 207 ->active_permissions() 208 ->HasEffectiveAccessToURL(GURL("http://news.ycombinator.com"))); 209 EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 210 211 extension = LoadManifest("effective_host_permissions", "all_hosts.json"); 212 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 213 EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/"))); 214 EXPECT_FALSE(hosts.MatchesURL(GURL("https://test/"))); 215 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 216 EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 217 218 extension = LoadManifest("effective_host_permissions", "all_hosts2.json"); 219 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 220 EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/"))); 221 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 222 EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 223 224 extension = LoadManifest("effective_host_permissions", "all_hosts3.json"); 225 hosts = extension->permissions_data()->GetEffectiveHostPermissions(); 226 EXPECT_FALSE(hosts.MatchesURL(GURL("http://test/"))); 227 EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/"))); 228 EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com"))); 229 EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts()); 230 } 231 232 TEST(ExtensionPermissionsTest, SocketPermissions) { 233 // Set feature current channel to appropriate value. 234 ScopedCurrentChannel scoped_channel(chrome::VersionInfo::CHANNEL_DEV); 235 scoped_refptr<Extension> extension; 236 std::string error; 237 238 extension = LoadManifest("socket_permissions", "empty.json"); 239 EXPECT_FALSE(CheckSocketPermission(extension, 240 SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); 241 242 extension = LoadManifestUnchecked("socket_permissions", 243 "socket1.json", 244 Manifest::INTERNAL, Extension::NO_FLAGS, 245 &error); 246 EXPECT_TRUE(extension.get() == NULL); 247 std::string expected_error_msg_header = ErrorUtils::FormatErrorMessage( 248 manifest_errors::kInvalidPermissionWithDetail, 249 "socket", 250 "NULL or empty permission list"); 251 EXPECT_EQ(expected_error_msg_header, error); 252 253 extension = LoadManifest("socket_permissions", "socket2.json"); 254 EXPECT_TRUE(CheckSocketPermission(extension, 255 SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80)); 256 EXPECT_FALSE(CheckSocketPermission( 257 extension, SocketPermissionRequest::UDP_BIND, "", 80)); 258 EXPECT_TRUE(CheckSocketPermission( 259 extension, SocketPermissionRequest::UDP_BIND, "", 8888)); 260 261 EXPECT_FALSE(CheckSocketPermission( 262 extension, SocketPermissionRequest::UDP_SEND_TO, "example.com", 1900)); 263 EXPECT_TRUE(CheckSocketPermission( 264 extension, 265 SocketPermissionRequest::UDP_SEND_TO, 266 "239.255.255.250", 1900)); 267 } 268 269 TEST(ExtensionPermissionsTest, RequiresActionForScriptExecution) { 270 // Extensions with all_hosts should require action. 271 EXPECT_TRUE(RequiresActionForScriptExecution( 272 "all_hosts_permissions", kAllHostsPermission, Manifest::INTERNAL)); 273 // Extensions with nearly all hosts are treated the same way. 274 EXPECT_TRUE(RequiresActionForScriptExecution( 275 "pseudo_all_hosts_permissions", "*://*.com/*", Manifest::INTERNAL)); 276 // Extensions with explicit permissions shouldn't require action. 277 EXPECT_FALSE(RequiresActionForScriptExecution( 278 "explicit_permissions", "https://www.google.com/*", Manifest::INTERNAL)); 279 // Policy extensions are exempt... 280 EXPECT_FALSE(RequiresActionForScriptExecution( 281 "policy", kAllHostsPermission, Manifest::EXTERNAL_POLICY)); 282 // ... as are component extensions. 283 EXPECT_FALSE(RequiresActionForScriptExecution( 284 "component", kAllHostsPermission, Manifest::COMPONENT)); 285 // Throw in an external pref extension to make sure that it's not just working 286 // for everything non-internal. 287 EXPECT_TRUE(RequiresActionForScriptExecution( 288 "external_pref", kAllHostsPermission, Manifest::EXTERNAL_PREF)); 289 290 // If we grant an extension tab permissions, then it should no longer require 291 // action. 292 scoped_refptr<const Extension> extension = 293 GetExtensionWithHostPermission("all_hosts_permissions", 294 kAllHostsPermission, 295 Manifest::INTERNAL); 296 URLPatternSet allowed_hosts; 297 allowed_hosts.AddPattern( 298 URLPattern(URLPattern::SCHEME_HTTPS, "https://www.google.com/*")); 299 scoped_refptr<PermissionSet> tab_permissions( 300 new PermissionSet(APIPermissionSet(), 301 ManifestPermissionSet(), 302 allowed_hosts, 303 URLPatternSet())); 304 extension->permissions_data()->UpdateTabSpecificPermissions(0, 305 tab_permissions); 306 EXPECT_FALSE(extension->permissions_data()->RequiresActionForScriptExecution( 307 extension, 0, GURL("https://www.google.com/"))); 308 } 309 310 TEST(ExtensionPermissionsTest, IsRestrictedUrl) { 311 scoped_refptr<const Extension> extension = 312 GetExtensionWithHostPermission("normal_extension", 313 kAllHostsPermission, 314 Manifest::INTERNAL); 315 // Chrome urls should be blocked for normal extensions. 316 CheckRestrictedUrls(extension, true); 317 318 scoped_refptr<const Extension> component = 319 GetExtensionWithHostPermission("component", 320 kAllHostsPermission, 321 Manifest::COMPONENT); 322 // Chrome urls should be accessible by component extensions. 323 CheckRestrictedUrls(component, false); 324 325 base::CommandLine::ForCurrentProcess()->AppendSwitch( 326 switches::kExtensionsOnChromeURLs); 327 // Enabling the switch should allow all extensions to access chrome urls. 328 CheckRestrictedUrls(extension, false); 329 330 } 331 332 TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyAPIPermissions) { 333 scoped_refptr<Extension> extension; 334 extension = LoadManifest("permissions", "many-apis.json"); 335 std::vector<base::string16> warnings = 336 extension->permissions_data()->GetPermissionMessageStrings(); 337 // Warning for "tabs" is suppressed by "history" permission. 338 ASSERT_EQ(5u, warnings.size()); 339 EXPECT_EQ("Read and modify your data on api.flickr.com", 340 UTF16ToUTF8(warnings[0])); 341 EXPECT_EQ("Read and modify your bookmarks", UTF16ToUTF8(warnings[1])); 342 EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[2])); 343 EXPECT_EQ("Read and modify your browsing history", UTF16ToUTF8(warnings[3])); 344 EXPECT_EQ("Manage your apps, extensions, and themes", 345 UTF16ToUTF8(warnings[4])); 346 } 347 348 TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHostsPermissions) { 349 scoped_refptr<Extension> extension; 350 extension = LoadManifest("permissions", "more-than-3-hosts.json"); 351 std::vector<base::string16> warnings = 352 extension->permissions_data()->GetPermissionMessageStrings(); 353 std::vector<base::string16> warnings_details = 354 extension->permissions_data()->GetPermissionMessageDetailsStrings(); 355 ASSERT_EQ(1u, warnings.size()); 356 ASSERT_EQ(1u, warnings_details.size()); 357 EXPECT_EQ("Read and modify your data on 5 websites", 358 UTF16ToUTF8(warnings[0])); 359 EXPECT_EQ("- www.a.com\n- www.b.com\n- www.c.com\n- www.d.com\n- www.e.com", 360 UTF16ToUTF8(warnings_details[0])); 361 } 362 363 TEST(ExtensionPermissionsTest, GetPermissionMessages_LocationApiPermission) { 364 scoped_refptr<Extension> extension; 365 extension = LoadManifest("permissions", 366 "location-api.json", 367 Manifest::COMPONENT, 368 Extension::NO_FLAGS); 369 std::vector<base::string16> warnings = 370 extension->permissions_data()->GetPermissionMessageStrings(); 371 ASSERT_EQ(1u, warnings.size()); 372 EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[0])); 373 } 374 375 TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHosts) { 376 scoped_refptr<Extension> extension; 377 extension = LoadManifest("permissions", "many-hosts.json"); 378 std::vector<base::string16> warnings = 379 extension->permissions_data()->GetPermissionMessageStrings(); 380 ASSERT_EQ(1u, warnings.size()); 381 EXPECT_EQ( 382 "Read and modify your data on encrypted.google.com and www.google.com", 383 UTF16ToUTF8(warnings[0])); 384 } 385 386 TEST(ExtensionPermissionsTest, GetPermissionMessages_Plugins) { 387 scoped_refptr<Extension> extension; 388 extension = LoadManifest("permissions", "plugins.json"); 389 std::vector<base::string16> warnings = 390 extension->permissions_data()->GetPermissionMessageStrings(); 391 // We don't parse the plugins key on Chrome OS, so it should not ask for any 392 // permissions. 393 #if defined(OS_CHROMEOS) 394 ASSERT_EQ(0u, warnings.size()); 395 #else 396 ASSERT_EQ(1u, warnings.size()); 397 EXPECT_EQ( 398 "Read and modify all your data on your computer and the websites you " 399 "visit", 400 UTF16ToUTF8(warnings[0])); 401 #endif 402 } 403 404 // Base class for testing the CanAccessPage and CanCaptureVisiblePage 405 // methods of Extension for extensions with various permissions. 406 class ExtensionScriptAndCaptureVisibleTest : public testing::Test { 407 protected: 408 ExtensionScriptAndCaptureVisibleTest() 409 : http_url("http://www.google.com"), 410 http_url_with_path("http://www.google.com/index.html"), 411 https_url("https://www.google.com"), 412 file_url("file:///foo/bar"), 413 favicon_url("chrome://favicon/http://www.google.com"), 414 extension_url("chrome-extension://" + 415 id_util::GenerateIdForPath( 416 base::FilePath(FILE_PATH_LITERAL("foo")))), 417 settings_url("chrome://settings"), 418 about_url("about:flags") { 419 urls_.insert(http_url); 420 urls_.insert(http_url_with_path); 421 urls_.insert(https_url); 422 urls_.insert(file_url); 423 urls_.insert(favicon_url); 424 urls_.insert(extension_url); 425 urls_.insert(settings_url); 426 urls_.insert(about_url); 427 // Ignore the policy delegate for this test. 428 PermissionsData::SetPolicyDelegate(NULL); 429 } 430 431 bool AllowedScript(const Extension* extension, const GURL& url, 432 const GURL& top_url) { 433 return AllowedScript(extension, url, top_url, -1); 434 } 435 436 bool AllowedScript(const Extension* extension, const GURL& url, 437 const GURL& top_url, int tab_id) { 438 return extension->permissions_data()->CanAccessPage( 439 extension, url, top_url, tab_id, -1, NULL); 440 } 441 442 bool BlockedScript(const Extension* extension, const GURL& url, 443 const GURL& top_url) { 444 return !extension->permissions_data()->CanAccessPage( 445 extension, url, top_url, -1, -1, NULL); 446 } 447 448 bool Allowed(const Extension* extension, const GURL& url) { 449 return Allowed(extension, url, -1); 450 } 451 452 bool Allowed(const Extension* extension, const GURL& url, int tab_id) { 453 return (extension->permissions_data()->CanAccessPage( 454 extension, url, url, tab_id, -1, NULL) && 455 extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL)); 456 } 457 458 bool CaptureOnly(const Extension* extension, const GURL& url) { 459 return CaptureOnly(extension, url, -1); 460 } 461 462 bool CaptureOnly(const Extension* extension, const GURL& url, int tab_id) { 463 return !extension->permissions_data()->CanAccessPage( 464 extension, url, url, tab_id, -1, NULL) && 465 extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL); 466 } 467 468 bool ScriptOnly(const Extension* extension, const GURL& url, 469 const GURL& top_url) { 470 return ScriptOnly(extension, url, top_url, -1); 471 } 472 473 bool ScriptOnly(const Extension* extension, const GURL& url, 474 const GURL& top_url, int tab_id) { 475 return AllowedScript(extension, url, top_url, tab_id) && 476 !extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL); 477 } 478 479 bool Blocked(const Extension* extension, const GURL& url) { 480 return Blocked(extension, url, -1); 481 } 482 483 bool Blocked(const Extension* extension, const GURL& url, int tab_id) { 484 return !(extension->permissions_data()->CanAccessPage( 485 extension, url, url, tab_id, -1, NULL) || 486 extension->permissions_data()->CanCaptureVisiblePage(tab_id, 487 NULL)); 488 } 489 490 bool ScriptAllowedExclusivelyOnTab( 491 const Extension* extension, 492 const std::set<GURL>& allowed_urls, 493 int tab_id) { 494 bool result = true; 495 for (std::set<GURL>::iterator it = urls_.begin(); it != urls_.end(); ++it) { 496 const GURL& url = *it; 497 if (allowed_urls.count(url)) 498 result &= AllowedScript(extension, url, url, tab_id); 499 else 500 result &= Blocked(extension, url, tab_id); 501 } 502 return result; 503 } 504 505 // URLs that are "safe" to provide scripting and capture visible tab access 506 // to if the permissions allow it. 507 const GURL http_url; 508 const GURL http_url_with_path; 509 const GURL https_url; 510 const GURL file_url; 511 512 // We should allow host permission but not scripting permission for favicon 513 // urls. 514 const GURL favicon_url; 515 516 // URLs that regular extensions should never get access to. 517 const GURL extension_url; 518 const GURL settings_url; 519 const GURL about_url; 520 521 private: 522 // The set of all URLs above. 523 std::set<GURL> urls_; 524 }; 525 526 TEST_F(ExtensionScriptAndCaptureVisibleTest, Permissions) { 527 // Test <all_urls> for regular extensions. 528 scoped_refptr<Extension> extension = LoadManifestStrict("script_and_capture", 529 "extension_regular_all.json"); 530 531 EXPECT_TRUE(Allowed(extension.get(), http_url)); 532 EXPECT_TRUE(Allowed(extension.get(), https_url)); 533 EXPECT_TRUE(CaptureOnly(extension.get(), file_url)); 534 EXPECT_TRUE(CaptureOnly(extension.get(), settings_url)); 535 EXPECT_TRUE(CaptureOnly(extension.get(), favicon_url)); 536 EXPECT_TRUE(CaptureOnly(extension.get(), about_url)); 537 EXPECT_TRUE(CaptureOnly(extension.get(), extension_url)); 538 539 // Test access to iframed content. 540 GURL within_extension_url = extension->GetResourceURL("page.html"); 541 EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path)); 542 EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path)); 543 EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url)); 544 EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url)); 545 EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url)); 546 EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url)); 547 548 EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url)); 549 EXPECT_FALSE(extension->permissions_data()->HasHostPermission(about_url)); 550 EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); 551 552 // Test * for scheme, which implies just the http/https schemes. 553 extension = LoadManifestStrict("script_and_capture", 554 "extension_wildcard.json"); 555 EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url)); 556 EXPECT_TRUE(ScriptOnly(extension.get(), https_url, https_url)); 557 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 558 EXPECT_TRUE(Blocked(extension.get(), about_url)); 559 EXPECT_TRUE(Blocked(extension.get(), file_url)); 560 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 561 extension = 562 LoadManifest("script_and_capture", "extension_wildcard_settings.json"); 563 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 564 565 // Having chrome://*/ should not work for regular extensions. Note that 566 // for favicon access, we require the explicit pattern chrome://favicon/*. 567 std::string error; 568 extension = LoadManifestUnchecked("script_and_capture", 569 "extension_wildcard_chrome.json", 570 Manifest::INTERNAL, Extension::NO_FLAGS, 571 &error); 572 std::vector<InstallWarning> warnings = extension->install_warnings(); 573 EXPECT_FALSE(warnings.empty()); 574 EXPECT_EQ(ErrorUtils::FormatErrorMessage( 575 manifest_errors::kInvalidPermissionScheme, 576 "chrome://*/"), 577 warnings[0].message); 578 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 579 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 580 EXPECT_TRUE(Blocked(extension.get(), about_url)); 581 582 // Having chrome://favicon/* should not give you chrome://* 583 extension = LoadManifestStrict("script_and_capture", 584 "extension_chrome_favicon_wildcard.json"); 585 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 586 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 587 EXPECT_TRUE(Blocked(extension.get(), about_url)); 588 EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); 589 590 // Having http://favicon should not give you chrome://favicon 591 extension = LoadManifestStrict("script_and_capture", 592 "extension_http_favicon.json"); 593 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 594 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 595 596 // Component extensions with <all_urls> should get everything. 597 extension = LoadManifest("script_and_capture", "extension_component_all.json", 598 Manifest::COMPONENT, Extension::NO_FLAGS); 599 EXPECT_TRUE(Allowed(extension.get(), http_url)); 600 EXPECT_TRUE(Allowed(extension.get(), https_url)); 601 EXPECT_TRUE(Allowed(extension.get(), settings_url)); 602 EXPECT_TRUE(Allowed(extension.get(), about_url)); 603 EXPECT_TRUE(Allowed(extension.get(), favicon_url)); 604 EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); 605 606 // Component extensions should only get access to what they ask for. 607 extension = LoadManifest("script_and_capture", 608 "extension_component_google.json", Manifest::COMPONENT, 609 Extension::NO_FLAGS); 610 EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url)); 611 EXPECT_TRUE(Blocked(extension.get(), https_url)); 612 EXPECT_TRUE(Blocked(extension.get(), file_url)); 613 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 614 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 615 EXPECT_TRUE(Blocked(extension.get(), about_url)); 616 EXPECT_TRUE(Blocked(extension.get(), extension_url)); 617 EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url)); 618 } 619 620 TEST_F(ExtensionScriptAndCaptureVisibleTest, PermissionsWithChromeURLsEnabled) { 621 CommandLine::ForCurrentProcess()->AppendSwitch( 622 switches::kExtensionsOnChromeURLs); 623 624 scoped_refptr<Extension> extension; 625 626 // Test <all_urls> for regular extensions. 627 extension = LoadManifestStrict("script_and_capture", 628 "extension_regular_all.json"); 629 EXPECT_TRUE(Allowed(extension.get(), http_url)); 630 EXPECT_TRUE(Allowed(extension.get(), https_url)); 631 EXPECT_TRUE(CaptureOnly(extension.get(), file_url)); 632 EXPECT_TRUE(CaptureOnly(extension.get(), settings_url)); 633 EXPECT_TRUE(Allowed(extension.get(), favicon_url)); // chrome:// requested 634 EXPECT_TRUE(CaptureOnly(extension.get(), about_url)); 635 EXPECT_TRUE(CaptureOnly(extension.get(), extension_url)); 636 637 // Test access to iframed content. 638 GURL within_extension_url = extension->GetResourceURL("page.html"); 639 EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path)); 640 EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path)); 641 EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url)); 642 EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url)); 643 EXPECT_TRUE(AllowedScript(extension.get(), http_url, extension_url)); 644 EXPECT_TRUE(AllowedScript(extension.get(), https_url, extension_url)); 645 646 const PermissionsData* permissions_data = extension->permissions_data(); 647 EXPECT_FALSE(permissions_data->HasHostPermission(settings_url)); 648 EXPECT_FALSE(permissions_data->HasHostPermission(about_url)); 649 EXPECT_TRUE(permissions_data->HasHostPermission(favicon_url)); 650 651 // Test * for scheme, which implies just the http/https schemes. 652 extension = LoadManifestStrict("script_and_capture", 653 "extension_wildcard.json"); 654 EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url)); 655 EXPECT_TRUE(ScriptOnly(extension.get(), https_url, https_url)); 656 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 657 EXPECT_TRUE(Blocked(extension.get(), about_url)); 658 EXPECT_TRUE(Blocked(extension.get(), file_url)); 659 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 660 extension = 661 LoadManifest("script_and_capture", "extension_wildcard_settings.json"); 662 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 663 664 // Having chrome://*/ should work for regular extensions with the flag 665 // enabled. 666 std::string error; 667 extension = LoadManifestUnchecked("script_and_capture", 668 "extension_wildcard_chrome.json", 669 Manifest::INTERNAL, Extension::NO_FLAGS, 670 &error); 671 EXPECT_FALSE(extension.get() == NULL); 672 EXPECT_TRUE(Blocked(extension.get(), http_url)); 673 EXPECT_TRUE(Blocked(extension.get(), https_url)); 674 EXPECT_TRUE(ScriptOnly(extension.get(), settings_url, settings_url)); 675 EXPECT_TRUE(Blocked(extension.get(), about_url)); 676 EXPECT_TRUE(Blocked(extension.get(), file_url)); 677 EXPECT_TRUE(ScriptOnly(extension.get(), favicon_url, favicon_url)); 678 679 // Having chrome://favicon/* should not give you chrome://* 680 extension = LoadManifestStrict("script_and_capture", 681 "extension_chrome_favicon_wildcard.json"); 682 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 683 EXPECT_TRUE(ScriptOnly(extension.get(), favicon_url, favicon_url)); 684 EXPECT_TRUE(Blocked(extension.get(), about_url)); 685 EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); 686 687 // Having http://favicon should not give you chrome://favicon 688 extension = LoadManifestStrict("script_and_capture", 689 "extension_http_favicon.json"); 690 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 691 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 692 693 // Component extensions with <all_urls> should get everything. 694 extension = LoadManifest("script_and_capture", "extension_component_all.json", 695 Manifest::COMPONENT, Extension::NO_FLAGS); 696 EXPECT_TRUE(Allowed(extension.get(), http_url)); 697 EXPECT_TRUE(Allowed(extension.get(), https_url)); 698 EXPECT_TRUE(Allowed(extension.get(), settings_url)); 699 EXPECT_TRUE(Allowed(extension.get(), about_url)); 700 EXPECT_TRUE(Allowed(extension.get(), favicon_url)); 701 EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url)); 702 703 // Component extensions should only get access to what they ask for. 704 extension = LoadManifest("script_and_capture", 705 "extension_component_google.json", Manifest::COMPONENT, 706 Extension::NO_FLAGS); 707 EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url)); 708 EXPECT_TRUE(Blocked(extension.get(), https_url)); 709 EXPECT_TRUE(Blocked(extension.get(), file_url)); 710 EXPECT_TRUE(Blocked(extension.get(), settings_url)); 711 EXPECT_TRUE(Blocked(extension.get(), favicon_url)); 712 EXPECT_TRUE(Blocked(extension.get(), about_url)); 713 EXPECT_TRUE(Blocked(extension.get(), extension_url)); 714 EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url)); 715 } 716 717 TEST_F(ExtensionScriptAndCaptureVisibleTest, TabSpecific) { 718 scoped_refptr<Extension> extension = 719 LoadManifestStrict("script_and_capture", "tab_specific.json"); 720 721 const PermissionsData* permissions_data = extension->permissions_data(); 722 EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0)); 723 EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(1)); 724 EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(2)); 725 726 std::set<GURL> no_urls; 727 728 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0)); 729 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1)); 730 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2)); 731 732 URLPatternSet allowed_hosts; 733 allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL, 734 http_url.spec())); 735 std::set<GURL> allowed_urls; 736 allowed_urls.insert(http_url); 737 // http_url_with_path() will also be allowed, because Extension should be 738 // considering the security origin of the URL not the URL itself, and 739 // http_url is in allowed_hosts. 740 allowed_urls.insert(http_url_with_path); 741 742 { 743 scoped_refptr<PermissionSet> permissions( 744 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), 745 allowed_hosts, URLPatternSet())); 746 permissions_data->UpdateTabSpecificPermissions(0, permissions); 747 EXPECT_EQ(permissions->explicit_hosts(), 748 permissions_data->GetTabSpecificPermissionsForTesting(0) 749 ->explicit_hosts()); 750 } 751 752 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), allowed_urls, 0)); 753 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1)); 754 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2)); 755 756 permissions_data->ClearTabSpecificPermissions(0); 757 EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0)); 758 759 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0)); 760 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1)); 761 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2)); 762 763 std::set<GURL> more_allowed_urls = allowed_urls; 764 more_allowed_urls.insert(https_url); 765 URLPatternSet more_allowed_hosts = allowed_hosts; 766 more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL, 767 https_url.spec())); 768 769 { 770 scoped_refptr<PermissionSet> permissions( 771 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), 772 allowed_hosts, URLPatternSet())); 773 permissions_data->UpdateTabSpecificPermissions(0, permissions); 774 EXPECT_EQ(permissions->explicit_hosts(), 775 permissions_data->GetTabSpecificPermissionsForTesting(0) 776 ->explicit_hosts()); 777 778 permissions = new PermissionSet(APIPermissionSet(), 779 ManifestPermissionSet(), 780 more_allowed_hosts, 781 URLPatternSet()); 782 permissions_data->UpdateTabSpecificPermissions(1, permissions); 783 EXPECT_EQ(permissions->explicit_hosts(), 784 permissions_data->GetTabSpecificPermissionsForTesting(1) 785 ->explicit_hosts()); 786 } 787 788 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), allowed_urls, 0)); 789 EXPECT_TRUE( 790 ScriptAllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1)); 791 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2)); 792 793 permissions_data->ClearTabSpecificPermissions(0); 794 EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0)); 795 796 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0)); 797 EXPECT_TRUE( 798 ScriptAllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1)); 799 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2)); 800 801 permissions_data->ClearTabSpecificPermissions(1); 802 EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(1)); 803 804 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0)); 805 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1)); 806 EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2)); 807 } 808 809 } // namespace extensions 810