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