Home | History | Annotate | Download | only in permissions
      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, &param);
     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