permissions_data_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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_switches.h"
12#include "chrome/common/chrome_version_info.h"
13#include "chrome/common/extensions/extension.h"
14#include "chrome/common/extensions/extension_manifest_constants.h"
15#include "chrome/common/extensions/extension_test_util.h"
16#include "chrome/common/extensions/features/feature.h"
17#include "chrome/common/extensions/permissions/api_permission.h"
18#include "chrome/common/extensions/permissions/permission_set.h"
19#include "chrome/common/extensions/permissions/permissions_data.h"
20#include "chrome/common/extensions/permissions/socket_permission.h"
21#include "content/public/common/socket_permission_request.h"
22#include "extensions/common/error_utils.h"
23#include "extensions/common/id_util.h"
24#include "extensions/common/url_pattern_set.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27using content::SocketPermissionRequest;
28using extension_test_util::LoadManifest;
29using extension_test_util::LoadManifestUnchecked;
30using extension_test_util::LoadManifestStrict;
31
32namespace extensions {
33
34namespace {
35
36bool CheckSocketPermission(
37    scoped_refptr<Extension> extension,
38    SocketPermissionRequest::OperationType type,
39    const char* host,
40    int port) {
41  SocketPermission::CheckParam param(type, host, port);
42  return PermissionsData::CheckAPIPermissionWithParam(
43      extension.get(), APIPermission::kSocket, &param);
44}
45
46}  // namespace
47
48TEST(ExtensionPermissionsTest, EffectiveHostPermissions) {
49  scoped_refptr<Extension> extension;
50  URLPatternSet hosts;
51
52  extension = LoadManifest("effective_host_permissions", "empty.json");
53  EXPECT_EQ(0u,
54            PermissionsData::GetEffectiveHostPermissions(extension.get())
55                .patterns().size());
56  EXPECT_FALSE(hosts.MatchesURL(GURL("http://www.google.com")));
57  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
58
59  extension = LoadManifest("effective_host_permissions", "one_host.json");
60  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
61  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
62  EXPECT_FALSE(hosts.MatchesURL(GURL("https://www.google.com")));
63  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
64
65  extension = LoadManifest("effective_host_permissions",
66                           "one_host_wildcard.json");
67  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
68  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
69  EXPECT_TRUE(hosts.MatchesURL(GURL("http://foo.google.com")));
70  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
71
72  extension = LoadManifest("effective_host_permissions", "two_hosts.json");
73  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
74  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
75  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
76  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
77
78  extension = LoadManifest("effective_host_permissions",
79                           "https_not_considered.json");
80  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
81  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
82  EXPECT_TRUE(hosts.MatchesURL(GURL("https://google.com")));
83  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
84
85  extension = LoadManifest("effective_host_permissions",
86                           "two_content_scripts.json");
87  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
88  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
89  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
90  EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL(
91      GURL("http://www.reddit.com")));
92  EXPECT_TRUE(hosts.MatchesURL(GURL("http://news.ycombinator.com")));
93  EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL(
94      GURL("http://news.ycombinator.com")));
95  EXPECT_FALSE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
96
97  extension = LoadManifest("effective_host_permissions", "all_hosts.json");
98  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
99  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
100  EXPECT_FALSE(hosts.MatchesURL(GURL("https://test/")));
101  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
102  EXPECT_TRUE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
103
104  extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
105  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
106  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
107  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
108  EXPECT_TRUE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
109
110  extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
111  hosts = PermissionsData::GetEffectiveHostPermissions(extension.get());
112  EXPECT_FALSE(hosts.MatchesURL(GURL("http://test/")));
113  EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/")));
114  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
115  EXPECT_TRUE(PermissionsData::HasEffectiveAccessToAllHosts(extension.get()));
116}
117
118TEST(ExtensionPermissionsTest, SocketPermissions) {
119  // Set feature current channel to appropriate value.
120  Feature::ScopedCurrentChannel scoped_channel(
121      chrome::VersionInfo::CHANNEL_DEV);
122  scoped_refptr<Extension> extension;
123  std::string error;
124
125  extension = LoadManifest("socket_permissions", "empty.json");
126  EXPECT_FALSE(CheckSocketPermission(extension,
127      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
128
129  extension = LoadManifestUnchecked("socket_permissions",
130                                    "socket1.json",
131                                    Manifest::INTERNAL, Extension::NO_FLAGS,
132                                    &error);
133  EXPECT_TRUE(extension.get() == NULL);
134  ASSERT_EQ(ErrorUtils::FormatErrorMessage(
135                extension_manifest_errors::kInvalidPermission, "socket"),
136            error);
137
138  extension = LoadManifest("socket_permissions", "socket2.json");
139  EXPECT_TRUE(CheckSocketPermission(extension,
140      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
141  EXPECT_FALSE(CheckSocketPermission(
142        extension, SocketPermissionRequest::UDP_BIND, "", 80));
143  EXPECT_TRUE(CheckSocketPermission(
144        extension, SocketPermissionRequest::UDP_BIND, "", 8888));
145
146  EXPECT_FALSE(CheckSocketPermission(
147        extension, SocketPermissionRequest::UDP_SEND_TO, "example.com", 1900));
148  EXPECT_TRUE(CheckSocketPermission(
149        extension,
150        SocketPermissionRequest::UDP_SEND_TO,
151        "239.255.255.250", 1900));
152}
153
154// This tests the API permissions with an empty manifest (one that just
155// specifies a name and a version and nothing else).
156TEST(ExtensionPermissionsTest, ApiPermissions) {
157  const struct {
158    const char* permission_name;
159    bool expect_success;
160  } kTests[] = {
161    // Negative test.
162    { "non_existing_permission", false },
163    // Test default module/package permission.
164    { "browserAction",  true },
165    { "devtools",       true },
166    { "extension",      true },
167    { "i18n",           true },
168    { "pageAction",     true },
169    { "pageActions",    true },
170    { "test",           true },
171    // Some negative tests.
172    { "bookmarks",      false },
173    { "cookies",        false },
174    { "history",        false },
175    // Make sure we find the module name after stripping '.' and '/'.
176    { "browserAction/abcd/onClick",  true },
177    { "browserAction.abcd.onClick",  true },
178    // Test Tabs functions.
179    { "tabs.create",      true},
180    { "tabs.duplicate",   true},
181    { "tabs.onRemoved",   true},
182    { "tabs.remove",      true},
183    { "tabs.update",      true},
184    { "tabs.getSelected", true},
185    { "tabs.onUpdated",   true },
186    // Test getPermissionWarnings functions. Only one requires permissions.
187    { "management.getPermissionWarningsById", false },
188    { "management.getPermissionWarningsByManifest", true },
189  };
190
191  scoped_refptr<Extension> extension;
192  extension = LoadManifest("empty_manifest", "empty.json");
193
194  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
195    EXPECT_EQ(kTests[i].expect_success,
196              extension->HasAPIPermission(kTests[i].permission_name))
197                  << "Permission being tested: " << kTests[i].permission_name;
198  }
199}
200
201TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyAPIPermissions) {
202  scoped_refptr<Extension> extension;
203  extension = LoadManifest("permissions", "many-apis.json");
204  std::vector<string16> warnings =
205      PermissionsData::GetPermissionMessageStrings(extension.get());
206  ASSERT_EQ(6u, warnings.size());
207  EXPECT_EQ("Access your data on api.flickr.com",
208            UTF16ToUTF8(warnings[0]));
209  EXPECT_EQ("Read and modify your bookmarks", UTF16ToUTF8(warnings[1]));
210  EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[2]));
211  EXPECT_EQ("Read and modify your browsing history", UTF16ToUTF8(warnings[3]));
212  EXPECT_EQ("Access your tabs and browsing activity", UTF16ToUTF8(warnings[4]));
213  EXPECT_EQ("Manage your apps, extensions, and themes",
214            UTF16ToUTF8(warnings[5]));
215}
216
217TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHostsPermissions) {
218  scoped_refptr<Extension> extension;
219  extension = LoadManifest("permissions", "more-than-3-hosts.json");
220  std::vector<string16> warnings =
221      PermissionsData::GetPermissionMessageStrings(extension.get());
222  std::vector<string16> warnings_details =
223      PermissionsData::GetPermissionMessageDetailsStrings(extension.get());
224  ASSERT_EQ(1u, warnings.size());
225  ASSERT_EQ(1u, warnings_details.size());
226#if defined(TOOLKIT_VIEWS)
227  EXPECT_EQ("Access your data on 5 website(s)", UTF16ToUTF8(warnings[0]));
228  EXPECT_EQ("- www.a.com\n- www.b.com\n- www.c.com\n- www.d.com\n- www.e.com",
229            UTF16ToUTF8(warnings_details[0]));
230#else
231  // TODO(finnur): Remove once other platforms support expandable sections.
232  EXPECT_EQ("Access your data on www.a.com, www.b.com, and 3 other websites",
233            UTF16ToUTF8(warnings[0]));
234  EXPECT_TRUE(warnings_details[0].empty());
235#endif
236}
237
238TEST(ExtensionPermissionsTest, GetPermissionMessages_LocationApiPermission) {
239  scoped_refptr<Extension> extension;
240  extension = LoadManifest("permissions",
241                           "location-api.json",
242                           Manifest::COMPONENT,
243                           Extension::NO_FLAGS);
244  std::vector<string16> warnings =
245      PermissionsData::GetPermissionMessageStrings(extension.get());
246  ASSERT_EQ(1u, warnings.size());
247  EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[0]));
248}
249
250TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHosts) {
251  scoped_refptr<Extension> extension;
252  extension = LoadManifest("permissions", "many-hosts.json");
253  std::vector<string16> warnings =
254      PermissionsData::GetPermissionMessageStrings(extension.get());
255  ASSERT_EQ(1u, warnings.size());
256  EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
257            UTF16ToUTF8(warnings[0]));
258}
259
260TEST(ExtensionPermissionsTest, GetPermissionMessages_Plugins) {
261  scoped_refptr<Extension> extension;
262  extension = LoadManifest("permissions", "plugins.json");
263  std::vector<string16> warnings =
264      PermissionsData::GetPermissionMessageStrings(extension.get());
265// We don't parse the plugins key on Chrome OS, so it should not ask for any
266// permissions.
267#if defined(OS_CHROMEOS)
268  ASSERT_EQ(0u, warnings.size());
269#else
270  ASSERT_EQ(1u, warnings.size());
271  EXPECT_EQ("Access all data on your computer and the websites you visit",
272            UTF16ToUTF8(warnings[0]));
273#endif
274}
275
276// Base class for testing the CanExecuteScriptOnPage and CanCaptureVisiblePage
277// methods of Extension for extensions with various permissions.
278class ExtensionScriptAndCaptureVisibleTest : public testing::Test {
279 protected:
280  ExtensionScriptAndCaptureVisibleTest()
281      : http_url("http://www.google.com"),
282        http_url_with_path("http://www.google.com/index.html"),
283        https_url("https://www.google.com"),
284        file_url("file:///foo/bar"),
285        favicon_url("chrome://favicon/http://www.google.com"),
286        extension_url("chrome-extension://" +
287            id_util::GenerateIdForPath(
288                base::FilePath(FILE_PATH_LITERAL("foo")))),
289        settings_url("chrome://settings"),
290        about_url("about:flags") {
291    urls_.insert(http_url);
292    urls_.insert(http_url_with_path);
293    urls_.insert(https_url);
294    urls_.insert(file_url);
295    urls_.insert(favicon_url);
296    urls_.insert(extension_url);
297    urls_.insert(settings_url);
298    urls_.insert(about_url);
299    // Ignore the policy delegate for this test.
300    PermissionsData::SetPolicyDelegate(NULL);
301  }
302
303  bool AllowedScript(const Extension* extension, const GURL& url,
304                     const GURL& top_url) {
305    return PermissionsData::CanExecuteScriptOnPage(
306        extension, url, top_url, -1, NULL, -1, NULL);
307  }
308
309  bool BlockedScript(const Extension* extension, const GURL& url,
310                     const GURL& top_url) {
311    return !PermissionsData::CanExecuteScriptOnPage(
312        extension, url, top_url, -1, NULL, -1, NULL);
313  }
314
315  bool Allowed(const Extension* extension, const GURL& url) {
316    return Allowed(extension, url, -1);
317  }
318
319  bool Allowed(const Extension* extension, const GURL& url, int tab_id) {
320    return (PermissionsData::CanExecuteScriptOnPage(
321                extension, url, url, tab_id, NULL, -1, NULL) &&
322            PermissionsData::CanCaptureVisiblePage(
323                extension, url, tab_id, NULL));
324  }
325
326  bool CaptureOnly(const Extension* extension, const GURL& url) {
327    return CaptureOnly(extension, url, -1);
328  }
329
330  bool CaptureOnly(const Extension* extension, const GURL& url, int tab_id) {
331    return !PermissionsData::CanExecuteScriptOnPage(
332                extension, url, url, tab_id, NULL, -1, NULL) &&
333           PermissionsData::CanCaptureVisiblePage(extension, url, tab_id, NULL);
334  }
335
336  bool Blocked(const Extension* extension, const GURL& url) {
337    return Blocked(extension, url, -1);
338  }
339
340  bool Blocked(const Extension* extension, const GURL& url, int tab_id) {
341    return !(PermissionsData::CanExecuteScriptOnPage(
342                 extension, url, url, tab_id, NULL, -1, NULL) ||
343             PermissionsData::CanCaptureVisiblePage(
344                 extension, url, tab_id, NULL));
345  }
346
347  bool AllowedExclusivelyOnTab(
348      const Extension* extension,
349      const std::set<GURL>& allowed_urls,
350      int tab_id) {
351    bool result = true;
352    for (std::set<GURL>::iterator it = urls_.begin(); it != urls_.end(); ++it) {
353      const GURL& url = *it;
354      if (allowed_urls.count(url))
355        result &= Allowed(extension, url, tab_id);
356      else
357        result &= Blocked(extension, url, tab_id);
358    }
359    return result;
360  }
361
362  // URLs that are "safe" to provide scripting and capture visible tab access
363  // to if the permissions allow it.
364  const GURL http_url;
365  const GURL http_url_with_path;
366  const GURL https_url;
367  const GURL file_url;
368
369  // We should allow host permission but not scripting permission for favicon
370  // urls.
371  const GURL favicon_url;
372
373  // URLs that regular extensions should never get access to.
374  const GURL extension_url;
375  const GURL settings_url;
376  const GURL about_url;
377
378 private:
379  // The set of all URLs above.
380  std::set<GURL> urls_;
381};
382
383TEST_F(ExtensionScriptAndCaptureVisibleTest, Permissions) {
384  // Test <all_urls> for regular extensions.
385  scoped_refptr<Extension> extension = LoadManifestStrict("script_and_capture",
386      "extension_regular_all.json");
387
388  EXPECT_TRUE(Allowed(extension.get(), http_url));
389  EXPECT_TRUE(Allowed(extension.get(), https_url));
390  EXPECT_TRUE(Blocked(extension.get(), file_url));
391  EXPECT_TRUE(Blocked(extension.get(), settings_url));
392  EXPECT_TRUE(CaptureOnly(extension.get(), favicon_url));
393  EXPECT_TRUE(Blocked(extension.get(), about_url));
394  EXPECT_TRUE(Blocked(extension.get(), extension_url));
395
396  // Test access to iframed content.
397  GURL within_extension_url = extension->GetResourceURL("page.html");
398  EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
399  EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
400  EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
401  EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
402  EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url));
403  EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url));
404
405  EXPECT_FALSE(
406      PermissionsData::HasHostPermission(extension.get(), settings_url));
407  EXPECT_FALSE(PermissionsData::HasHostPermission(extension.get(), about_url));
408  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
409
410  // Test * for scheme, which implies just the http/https schemes.
411  extension = LoadManifestStrict("script_and_capture",
412      "extension_wildcard.json");
413  EXPECT_TRUE(Allowed(extension.get(), http_url));
414  EXPECT_TRUE(Allowed(extension.get(), https_url));
415  EXPECT_TRUE(Blocked(extension.get(), settings_url));
416  EXPECT_TRUE(Blocked(extension.get(), about_url));
417  EXPECT_TRUE(Blocked(extension.get(), file_url));
418  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
419  extension =
420      LoadManifest("script_and_capture", "extension_wildcard_settings.json");
421  EXPECT_TRUE(Blocked(extension.get(), settings_url));
422
423  // Having chrome://*/ should not work for regular extensions. Note that
424  // for favicon access, we require the explicit pattern chrome://favicon/*.
425  std::string error;
426  extension = LoadManifestUnchecked("script_and_capture",
427                                    "extension_wildcard_chrome.json",
428                                    Manifest::INTERNAL, Extension::NO_FLAGS,
429                                    &error);
430  EXPECT_TRUE(extension.get() == NULL);
431  EXPECT_EQ(
432      ErrorUtils::FormatErrorMessage(
433          extension_manifest_errors::kInvalidPermissionScheme, "chrome://*/"),
434      error);
435
436  // Having chrome://favicon/* should not give you chrome://*
437  extension = LoadManifestStrict("script_and_capture",
438      "extension_chrome_favicon_wildcard.json");
439  EXPECT_TRUE(Blocked(extension.get(), settings_url));
440  EXPECT_TRUE(CaptureOnly(extension.get(), favicon_url));
441  EXPECT_TRUE(Blocked(extension.get(), about_url));
442  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
443
444  // Having http://favicon should not give you chrome://favicon
445  extension = LoadManifestStrict("script_and_capture",
446      "extension_http_favicon.json");
447  EXPECT_TRUE(Blocked(extension.get(), settings_url));
448  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
449
450  // Component extensions with <all_urls> should get everything.
451  extension = LoadManifest("script_and_capture", "extension_component_all.json",
452      Manifest::COMPONENT, Extension::NO_FLAGS);
453  EXPECT_TRUE(Allowed(extension.get(), http_url));
454  EXPECT_TRUE(Allowed(extension.get(), https_url));
455  EXPECT_TRUE(Allowed(extension.get(), settings_url));
456  EXPECT_TRUE(Allowed(extension.get(), about_url));
457  EXPECT_TRUE(Allowed(extension.get(), favicon_url));
458  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
459
460  // Component extensions should only get access to what they ask for.
461  extension = LoadManifest("script_and_capture",
462      "extension_component_google.json", Manifest::COMPONENT,
463      Extension::NO_FLAGS);
464  EXPECT_TRUE(Allowed(extension.get(), http_url));
465  EXPECT_TRUE(Blocked(extension.get(), https_url));
466  EXPECT_TRUE(Blocked(extension.get(), file_url));
467  EXPECT_TRUE(Blocked(extension.get(), settings_url));
468  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
469  EXPECT_TRUE(Blocked(extension.get(), about_url));
470  EXPECT_TRUE(Blocked(extension.get(), extension_url));
471  EXPECT_FALSE(
472      PermissionsData::HasHostPermission(extension.get(), settings_url));
473}
474
475TEST_F(ExtensionScriptAndCaptureVisibleTest, PermissionsWithChromeURLsEnabled) {
476  CommandLine::ForCurrentProcess()->AppendSwitch(
477      switches::kExtensionsOnChromeURLs);
478
479  scoped_refptr<Extension> extension;
480
481  // Test <all_urls> for regular extensions.
482  extension = LoadManifestStrict("script_and_capture",
483      "extension_regular_all.json");
484  EXPECT_TRUE(Allowed(extension.get(), http_url));
485  EXPECT_TRUE(Allowed(extension.get(), https_url));
486  EXPECT_TRUE(Blocked(extension.get(), file_url));
487  EXPECT_TRUE(Blocked(extension.get(), settings_url));
488  EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
489  EXPECT_TRUE(Blocked(extension.get(), about_url));
490  EXPECT_TRUE(Blocked(extension.get(), extension_url));
491
492  // Test access to iframed content.
493  GURL within_extension_url = extension->GetResourceURL("page.html");
494  EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
495  EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
496  EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
497  EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
498  EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url));
499  EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url));
500
501  EXPECT_FALSE(
502      PermissionsData::HasHostPermission(extension.get(), settings_url));
503  EXPECT_FALSE(PermissionsData::HasHostPermission(extension.get(), about_url));
504  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
505
506  // Test * for scheme, which implies just the http/https schemes.
507  extension = LoadManifestStrict("script_and_capture",
508      "extension_wildcard.json");
509  EXPECT_TRUE(Allowed(extension.get(), http_url));
510  EXPECT_TRUE(Allowed(extension.get(), https_url));
511  EXPECT_TRUE(Blocked(extension.get(), settings_url));
512  EXPECT_TRUE(Blocked(extension.get(), about_url));
513  EXPECT_TRUE(Blocked(extension.get(), file_url));
514  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
515  extension =
516      LoadManifest("script_and_capture", "extension_wildcard_settings.json");
517  EXPECT_TRUE(Blocked(extension.get(), settings_url));
518
519  // Having chrome://*/ should work for regular extensions with the flag
520  // enabled.
521  std::string error;
522  extension = LoadManifestUnchecked("script_and_capture",
523                                    "extension_wildcard_chrome.json",
524                                    Manifest::INTERNAL, Extension::NO_FLAGS,
525                                    &error);
526  EXPECT_FALSE(extension.get() == NULL);
527  EXPECT_TRUE(Blocked(extension.get(), http_url));
528  EXPECT_TRUE(Blocked(extension.get(), https_url));
529  EXPECT_TRUE(Allowed(extension.get(), settings_url));
530  EXPECT_TRUE(Blocked(extension.get(), about_url));
531  EXPECT_TRUE(Blocked(extension.get(), file_url));
532  EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
533
534  // Having chrome://favicon/* should not give you chrome://*
535  extension = LoadManifestStrict("script_and_capture",
536      "extension_chrome_favicon_wildcard.json");
537  EXPECT_TRUE(Blocked(extension.get(), settings_url));
538  EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
539  EXPECT_TRUE(Blocked(extension.get(), about_url));
540  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
541
542  // Having http://favicon should not give you chrome://favicon
543  extension = LoadManifestStrict("script_and_capture",
544      "extension_http_favicon.json");
545  EXPECT_TRUE(Blocked(extension.get(), settings_url));
546  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
547
548  // Component extensions with <all_urls> should get everything.
549  extension = LoadManifest("script_and_capture", "extension_component_all.json",
550      Manifest::COMPONENT, Extension::NO_FLAGS);
551  EXPECT_TRUE(Allowed(extension.get(), http_url));
552  EXPECT_TRUE(Allowed(extension.get(), https_url));
553  EXPECT_TRUE(Allowed(extension.get(), settings_url));
554  EXPECT_TRUE(Allowed(extension.get(), about_url));
555  EXPECT_TRUE(Allowed(extension.get(), favicon_url));
556  EXPECT_TRUE(PermissionsData::HasHostPermission(extension.get(), favicon_url));
557
558  // Component extensions should only get access to what they ask for.
559  extension = LoadManifest("script_and_capture",
560      "extension_component_google.json", Manifest::COMPONENT,
561      Extension::NO_FLAGS);
562  EXPECT_TRUE(Allowed(extension.get(), http_url));
563  EXPECT_TRUE(Blocked(extension.get(), https_url));
564  EXPECT_TRUE(Blocked(extension.get(), file_url));
565  EXPECT_TRUE(Blocked(extension.get(), settings_url));
566  EXPECT_TRUE(Blocked(extension.get(), favicon_url));
567  EXPECT_TRUE(Blocked(extension.get(), about_url));
568  EXPECT_TRUE(Blocked(extension.get(), extension_url));
569  EXPECT_FALSE(
570      PermissionsData::HasHostPermission(extension.get(), settings_url));
571}
572
573TEST_F(ExtensionScriptAndCaptureVisibleTest, TabSpecific) {
574  scoped_refptr<Extension> extension =
575      LoadManifestStrict("script_and_capture", "tab_specific.json");
576
577  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
578                   .get());
579  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 1)
580                   .get());
581  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 2)
582                   .get());
583
584  std::set<GURL> no_urls;
585
586  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
587  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
588  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
589
590  URLPatternSet allowed_hosts;
591  allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
592                                      http_url.spec()));
593  std::set<GURL> allowed_urls;
594  allowed_urls.insert(http_url);
595  // http_url_with_path() will also be allowed, because Extension should be
596  // considering the security origin of the URL not the URL itself, and
597  // http_url is in allowed_hosts.
598  allowed_urls.insert(http_url_with_path);
599
600  {
601    scoped_refptr<PermissionSet> permissions(
602        new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet()));
603    PermissionsData::UpdateTabSpecificPermissions(
604        extension.get(), 0, permissions);
605    EXPECT_EQ(permissions->explicit_hosts(),
606              PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
607                  ->explicit_hosts());
608  }
609
610  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
611  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
612  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
613
614  PermissionsData::ClearTabSpecificPermissions(extension.get(), 0);
615  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
616                   .get());
617
618  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
619  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
620  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
621
622  std::set<GURL> more_allowed_urls = allowed_urls;
623  more_allowed_urls.insert(https_url);
624  URLPatternSet more_allowed_hosts = allowed_hosts;
625  more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
626                                           https_url.spec()));
627
628  {
629    scoped_refptr<PermissionSet> permissions(
630        new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet()));
631    PermissionsData::UpdateTabSpecificPermissions(
632        extension.get(), 0, permissions);
633    EXPECT_EQ(permissions->explicit_hosts(),
634              PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
635                  ->explicit_hosts());
636
637    permissions = new PermissionSet(APIPermissionSet(),
638                                    more_allowed_hosts,
639                                    URLPatternSet());
640    PermissionsData::UpdateTabSpecificPermissions(
641        extension.get(), 1, permissions);
642    EXPECT_EQ(permissions->explicit_hosts(),
643              PermissionsData::GetTabSpecificPermissions(extension.get(), 1)
644                  ->explicit_hosts());
645  }
646
647  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
648  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
649  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
650
651  PermissionsData::ClearTabSpecificPermissions(extension.get(), 0);
652  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 0)
653                   .get());
654
655  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
656  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
657  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
658
659  PermissionsData::ClearTabSpecificPermissions(extension.get(), 1);
660  EXPECT_FALSE(PermissionsData::GetTabSpecificPermissions(extension.get(), 1)
661                   .get());
662
663  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 0));
664  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 1));
665  EXPECT_TRUE(AllowedExclusivelyOnTab(extension.get(), no_urls, 2));
666}
667
668}  // namespace extensions
669