dc3aa8697f527aa05b4d9df960a992d8db4b5195
[platform/framework/web/crosswalk.git] / src / extensions / common / permissions / permissions_data_unittest.cc
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 }  // namespace
91
92 TEST(ExtensionPermissionsTest, EffectiveHostPermissions) {
93   scoped_refptr<Extension> extension;
94   URLPatternSet hosts;
95
96   extension = LoadManifest("effective_host_permissions", "empty.json");
97   EXPECT_EQ(0u,
98             extension->permissions_data()
99                 ->GetEffectiveHostPermissions()
100                 .patterns()
101                 .size());
102   EXPECT_FALSE(hosts.MatchesURL(GURL("http://www.google.com")));
103   EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
104
105   extension = LoadManifest("effective_host_permissions", "one_host.json");
106   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
107   EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
108   EXPECT_FALSE(hosts.MatchesURL(GURL("https://www.google.com")));
109   EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
110
111   extension = LoadManifest("effective_host_permissions",
112                            "one_host_wildcard.json");
113   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
114   EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
115   EXPECT_TRUE(hosts.MatchesURL(GURL("http://foo.google.com")));
116   EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
117
118   extension = LoadManifest("effective_host_permissions", "two_hosts.json");
119   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
120   EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
121   EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
122   EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
123
124   extension = LoadManifest("effective_host_permissions",
125                            "https_not_considered.json");
126   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
127   EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
128   EXPECT_TRUE(hosts.MatchesURL(GURL("https://google.com")));
129   EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
130
131   extension = LoadManifest("effective_host_permissions",
132                            "two_content_scripts.json");
133   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
134   EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
135   EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
136   EXPECT_TRUE(extension->permissions_data()
137                   ->active_permissions()
138                   ->HasEffectiveAccessToURL(GURL("http://www.reddit.com")));
139   EXPECT_TRUE(hosts.MatchesURL(GURL("http://news.ycombinator.com")));
140   EXPECT_TRUE(
141       extension->permissions_data()
142           ->active_permissions()
143           ->HasEffectiveAccessToURL(GURL("http://news.ycombinator.com")));
144   EXPECT_FALSE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
145
146   extension = LoadManifest("effective_host_permissions", "all_hosts.json");
147   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
148   EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
149   EXPECT_FALSE(hosts.MatchesURL(GURL("https://test/")));
150   EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
151   EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
152
153   extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
154   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
155   EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
156   EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
157   EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
158
159   extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
160   hosts = extension->permissions_data()->GetEffectiveHostPermissions();
161   EXPECT_FALSE(hosts.MatchesURL(GURL("http://test/")));
162   EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/")));
163   EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
164   EXPECT_TRUE(extension->permissions_data()->HasEffectiveAccessToAllHosts());
165 }
166
167 TEST(ExtensionPermissionsTest, SocketPermissions) {
168   // Set feature current channel to appropriate value.
169   ScopedCurrentChannel scoped_channel(chrome::VersionInfo::CHANNEL_DEV);
170   scoped_refptr<Extension> extension;
171   std::string error;
172
173   extension = LoadManifest("socket_permissions", "empty.json");
174   EXPECT_FALSE(CheckSocketPermission(extension,
175       SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
176
177   extension = LoadManifestUnchecked("socket_permissions",
178                                     "socket1.json",
179                                     Manifest::INTERNAL, Extension::NO_FLAGS,
180                                     &error);
181   EXPECT_TRUE(extension.get() == NULL);
182   std::string expected_error_msg_header = ErrorUtils::FormatErrorMessage(
183       manifest_errors::kInvalidPermissionWithDetail,
184       "socket",
185       "NULL or empty permission list");
186   EXPECT_EQ(expected_error_msg_header, error);
187
188   extension = LoadManifest("socket_permissions", "socket2.json");
189   EXPECT_TRUE(CheckSocketPermission(extension,
190       SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
191   EXPECT_FALSE(CheckSocketPermission(
192         extension, SocketPermissionRequest::UDP_BIND, "", 80));
193   EXPECT_TRUE(CheckSocketPermission(
194         extension, SocketPermissionRequest::UDP_BIND, "", 8888));
195
196   EXPECT_FALSE(CheckSocketPermission(
197         extension, SocketPermissionRequest::UDP_SEND_TO, "example.com", 1900));
198   EXPECT_TRUE(CheckSocketPermission(
199         extension,
200         SocketPermissionRequest::UDP_SEND_TO,
201         "239.255.255.250", 1900));
202 }
203
204 TEST(ExtensionPermissionsTest, RequiresActionForScriptExecution) {
205   // Extensions with all_hosts should require action.
206   EXPECT_TRUE(RequiresActionForScriptExecution(
207       "all_hosts_permissions", kAllHostsPermission, Manifest::INTERNAL));
208   // Extensions with nearly all hosts are treated the same way.
209   EXPECT_TRUE(RequiresActionForScriptExecution(
210       "pseudo_all_hosts_permissions", "*://*.com/*", Manifest::INTERNAL));
211   // Extensions with explicit permissions shouldn't require action.
212   EXPECT_FALSE(RequiresActionForScriptExecution(
213       "explicit_permissions", "https://www.google.com/*", Manifest::INTERNAL));
214   // Policy extensions are exempt...
215   EXPECT_FALSE(RequiresActionForScriptExecution(
216       "policy", kAllHostsPermission, Manifest::EXTERNAL_POLICY));
217   // ... as are component extensions.
218   EXPECT_FALSE(RequiresActionForScriptExecution(
219       "component", kAllHostsPermission, Manifest::COMPONENT));
220   // Throw in an external pref extension to make sure that it's not just working
221   // for everything non-internal.
222   EXPECT_TRUE(RequiresActionForScriptExecution(
223       "external_pref", kAllHostsPermission, Manifest::EXTERNAL_PREF));
224
225   // If we grant an extension tab permissions, then it should no longer require
226   // action.
227   scoped_refptr<const Extension> extension =
228       GetExtensionWithHostPermission("all_hosts_permissions",
229                                      kAllHostsPermission,
230                                      Manifest::INTERNAL);
231   URLPatternSet allowed_hosts;
232   allowed_hosts.AddPattern(
233       URLPattern(URLPattern::SCHEME_HTTPS, "https://www.google.com/*"));
234   scoped_refptr<PermissionSet> tab_permissions(
235       new PermissionSet(APIPermissionSet(),
236                         ManifestPermissionSet(),
237                         allowed_hosts,
238                         URLPatternSet()));
239   extension->permissions_data()->UpdateTabSpecificPermissions(0,
240                                                               tab_permissions);
241   EXPECT_FALSE(extension->permissions_data()->RequiresActionForScriptExecution(
242       extension, 0, GURL("https://www.google.com/")));
243 }
244
245 TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyAPIPermissions) {
246   scoped_refptr<Extension> extension;
247   extension = LoadManifest("permissions", "many-apis.json");
248   std::vector<base::string16> warnings =
249       extension->permissions_data()->GetPermissionMessageStrings();
250   // Warning for "tabs" is suppressed by "history" permission.
251   ASSERT_EQ(5u, warnings.size());
252   EXPECT_EQ("Read and modify your data on api.flickr.com",
253             UTF16ToUTF8(warnings[0]));
254   EXPECT_EQ("Read and modify your bookmarks", UTF16ToUTF8(warnings[1]));
255   EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[2]));
256   EXPECT_EQ("Read and modify your browsing history", UTF16ToUTF8(warnings[3]));
257   EXPECT_EQ("Manage your apps, extensions, and themes",
258             UTF16ToUTF8(warnings[4]));
259 }
260
261 TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHostsPermissions) {
262   scoped_refptr<Extension> extension;
263   extension = LoadManifest("permissions", "more-than-3-hosts.json");
264   std::vector<base::string16> warnings =
265       extension->permissions_data()->GetPermissionMessageStrings();
266   std::vector<base::string16> warnings_details =
267       extension->permissions_data()->GetPermissionMessageDetailsStrings();
268   ASSERT_EQ(1u, warnings.size());
269   ASSERT_EQ(1u, warnings_details.size());
270   EXPECT_EQ("Read and modify your data on 5 websites",
271             UTF16ToUTF8(warnings[0]));
272   EXPECT_EQ("- www.a.com\n- www.b.com\n- www.c.com\n- www.d.com\n- www.e.com",
273             UTF16ToUTF8(warnings_details[0]));
274 }
275
276 TEST(ExtensionPermissionsTest, GetPermissionMessages_LocationApiPermission) {
277   scoped_refptr<Extension> extension;
278   extension = LoadManifest("permissions",
279                            "location-api.json",
280                            Manifest::COMPONENT,
281                            Extension::NO_FLAGS);
282   std::vector<base::string16> warnings =
283       extension->permissions_data()->GetPermissionMessageStrings();
284   ASSERT_EQ(1u, warnings.size());
285   EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[0]));
286 }
287
288 TEST(ExtensionPermissionsTest, GetPermissionMessages_ManyHosts) {
289   scoped_refptr<Extension> extension;
290   extension = LoadManifest("permissions", "many-hosts.json");
291   std::vector<base::string16> warnings =
292       extension->permissions_data()->GetPermissionMessageStrings();
293   ASSERT_EQ(1u, warnings.size());
294   EXPECT_EQ(
295       "Read and modify your data on encrypted.google.com and www.google.com",
296       UTF16ToUTF8(warnings[0]));
297 }
298
299 TEST(ExtensionPermissionsTest, GetPermissionMessages_Plugins) {
300   scoped_refptr<Extension> extension;
301   extension = LoadManifest("permissions", "plugins.json");
302   std::vector<base::string16> warnings =
303       extension->permissions_data()->GetPermissionMessageStrings();
304 // We don't parse the plugins key on Chrome OS, so it should not ask for any
305 // permissions.
306 #if defined(OS_CHROMEOS)
307   ASSERT_EQ(0u, warnings.size());
308 #else
309   ASSERT_EQ(1u, warnings.size());
310   EXPECT_EQ(
311       "Read and modify all your data on your computer and the websites you "
312       "visit",
313       UTF16ToUTF8(warnings[0]));
314 #endif
315 }
316
317 // Base class for testing the CanAccessPage and CanCaptureVisiblePage
318 // methods of Extension for extensions with various permissions.
319 class ExtensionScriptAndCaptureVisibleTest : public testing::Test {
320  protected:
321   ExtensionScriptAndCaptureVisibleTest()
322       : http_url("http://www.google.com"),
323         http_url_with_path("http://www.google.com/index.html"),
324         https_url("https://www.google.com"),
325         file_url("file:///foo/bar"),
326         favicon_url("chrome://favicon/http://www.google.com"),
327         extension_url("chrome-extension://" +
328             id_util::GenerateIdForPath(
329                 base::FilePath(FILE_PATH_LITERAL("foo")))),
330         settings_url("chrome://settings"),
331         about_url("about:flags") {
332     urls_.insert(http_url);
333     urls_.insert(http_url_with_path);
334     urls_.insert(https_url);
335     urls_.insert(file_url);
336     urls_.insert(favicon_url);
337     urls_.insert(extension_url);
338     urls_.insert(settings_url);
339     urls_.insert(about_url);
340     // Ignore the policy delegate for this test.
341     PermissionsData::SetPolicyDelegate(NULL);
342   }
343
344   bool AllowedScript(const Extension* extension, const GURL& url,
345                      const GURL& top_url) {
346     return AllowedScript(extension, url, top_url, -1);
347   }
348
349   bool AllowedScript(const Extension* extension, const GURL& url,
350                      const GURL& top_url, int tab_id) {
351     return extension->permissions_data()->CanAccessPage(
352         extension, url, top_url, tab_id, -1, NULL);
353   }
354
355   bool BlockedScript(const Extension* extension, const GURL& url,
356                      const GURL& top_url) {
357     return !extension->permissions_data()->CanAccessPage(
358         extension, url, top_url, -1, -1, NULL);
359   }
360
361   bool Allowed(const Extension* extension, const GURL& url) {
362     return Allowed(extension, url, -1);
363   }
364
365   bool Allowed(const Extension* extension, const GURL& url, int tab_id) {
366     return (extension->permissions_data()->CanAccessPage(
367                 extension, url, url, tab_id, -1, NULL) &&
368             extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL));
369   }
370
371   bool CaptureOnly(const Extension* extension, const GURL& url) {
372     return CaptureOnly(extension, url, -1);
373   }
374
375   bool CaptureOnly(const Extension* extension, const GURL& url, int tab_id) {
376     return !extension->permissions_data()->CanAccessPage(
377                extension, url, url, tab_id, -1, NULL) &&
378            extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL);
379   }
380
381   bool ScriptOnly(const Extension* extension, const GURL& url,
382                   const GURL& top_url) {
383     return ScriptOnly(extension, url, top_url, -1);
384   }
385
386   bool ScriptOnly(const Extension* extension, const GURL& url,
387                   const GURL& top_url, int tab_id) {
388     return AllowedScript(extension, url, top_url, tab_id) &&
389            !extension->permissions_data()->CanCaptureVisiblePage(tab_id, NULL);
390   }
391
392   bool Blocked(const Extension* extension, const GURL& url) {
393     return Blocked(extension, url, -1);
394   }
395
396   bool Blocked(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,
400                                                                   NULL));
401   }
402
403   bool ScriptAllowedExclusivelyOnTab(
404       const Extension* extension,
405       const std::set<GURL>& allowed_urls,
406       int tab_id) {
407     bool result = true;
408     for (std::set<GURL>::iterator it = urls_.begin(); it != urls_.end(); ++it) {
409       const GURL& url = *it;
410       if (allowed_urls.count(url))
411         result &= AllowedScript(extension, url, url, tab_id);
412       else
413         result &= Blocked(extension, url, tab_id);
414     }
415     return result;
416   }
417
418   // URLs that are "safe" to provide scripting and capture visible tab access
419   // to if the permissions allow it.
420   const GURL http_url;
421   const GURL http_url_with_path;
422   const GURL https_url;
423   const GURL file_url;
424
425   // We should allow host permission but not scripting permission for favicon
426   // urls.
427   const GURL favicon_url;
428
429   // URLs that regular extensions should never get access to.
430   const GURL extension_url;
431   const GURL settings_url;
432   const GURL about_url;
433
434  private:
435   // The set of all URLs above.
436   std::set<GURL> urls_;
437 };
438
439 TEST_F(ExtensionScriptAndCaptureVisibleTest, Permissions) {
440   // Test <all_urls> for regular extensions.
441   scoped_refptr<Extension> extension = LoadManifestStrict("script_and_capture",
442       "extension_regular_all.json");
443
444   EXPECT_TRUE(Allowed(extension.get(), http_url));
445   EXPECT_TRUE(Allowed(extension.get(), https_url));
446   EXPECT_TRUE(CaptureOnly(extension.get(), file_url));
447   EXPECT_TRUE(CaptureOnly(extension.get(), settings_url));
448   EXPECT_TRUE(CaptureOnly(extension.get(), favicon_url));
449   EXPECT_TRUE(CaptureOnly(extension.get(), about_url));
450   EXPECT_TRUE(CaptureOnly(extension.get(), extension_url));
451
452   // Test access to iframed content.
453   GURL within_extension_url = extension->GetResourceURL("page.html");
454   EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
455   EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
456   EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
457   EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
458   EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url));
459   EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url));
460
461   EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url));
462   EXPECT_FALSE(extension->permissions_data()->HasHostPermission(about_url));
463   EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));
464
465   // Test * for scheme, which implies just the http/https schemes.
466   extension = LoadManifestStrict("script_and_capture",
467       "extension_wildcard.json");
468   EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
469   EXPECT_TRUE(ScriptOnly(extension.get(), https_url, https_url));
470   EXPECT_TRUE(Blocked(extension.get(), settings_url));
471   EXPECT_TRUE(Blocked(extension.get(), about_url));
472   EXPECT_TRUE(Blocked(extension.get(), file_url));
473   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
474   extension =
475       LoadManifest("script_and_capture", "extension_wildcard_settings.json");
476   EXPECT_TRUE(Blocked(extension.get(), settings_url));
477
478   // Having chrome://*/ should not work for regular extensions. Note that
479   // for favicon access, we require the explicit pattern chrome://favicon/*.
480   std::string error;
481   extension = LoadManifestUnchecked("script_and_capture",
482                                     "extension_wildcard_chrome.json",
483                                     Manifest::INTERNAL, Extension::NO_FLAGS,
484                                     &error);
485   std::vector<InstallWarning> warnings = extension->install_warnings();
486   EXPECT_FALSE(warnings.empty());
487   EXPECT_EQ(ErrorUtils::FormatErrorMessage(
488                 manifest_errors::kInvalidPermissionScheme,
489                 "chrome://*/"),
490             warnings[0].message);
491   EXPECT_TRUE(Blocked(extension.get(), settings_url));
492   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
493   EXPECT_TRUE(Blocked(extension.get(), about_url));
494
495   // Having chrome://favicon/* should not give you chrome://*
496   extension = LoadManifestStrict("script_and_capture",
497       "extension_chrome_favicon_wildcard.json");
498   EXPECT_TRUE(Blocked(extension.get(), settings_url));
499   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
500   EXPECT_TRUE(Blocked(extension.get(), about_url));
501   EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));
502
503   // Having http://favicon should not give you chrome://favicon
504   extension = LoadManifestStrict("script_and_capture",
505       "extension_http_favicon.json");
506   EXPECT_TRUE(Blocked(extension.get(), settings_url));
507   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
508
509   // Component extensions with <all_urls> should get everything.
510   extension = LoadManifest("script_and_capture", "extension_component_all.json",
511       Manifest::COMPONENT, Extension::NO_FLAGS);
512   EXPECT_TRUE(Allowed(extension.get(), http_url));
513   EXPECT_TRUE(Allowed(extension.get(), https_url));
514   EXPECT_TRUE(Allowed(extension.get(), settings_url));
515   EXPECT_TRUE(Allowed(extension.get(), about_url));
516   EXPECT_TRUE(Allowed(extension.get(), favicon_url));
517   EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));
518
519   // Component extensions should only get access to what they ask for.
520   extension = LoadManifest("script_and_capture",
521       "extension_component_google.json", Manifest::COMPONENT,
522       Extension::NO_FLAGS);
523   EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
524   EXPECT_TRUE(Blocked(extension.get(), https_url));
525   EXPECT_TRUE(Blocked(extension.get(), file_url));
526   EXPECT_TRUE(Blocked(extension.get(), settings_url));
527   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
528   EXPECT_TRUE(Blocked(extension.get(), about_url));
529   EXPECT_TRUE(Blocked(extension.get(), extension_url));
530   EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url));
531 }
532
533 TEST_F(ExtensionScriptAndCaptureVisibleTest, PermissionsWithChromeURLsEnabled) {
534   CommandLine::ForCurrentProcess()->AppendSwitch(
535       switches::kExtensionsOnChromeURLs);
536
537   scoped_refptr<Extension> extension;
538
539   // Test <all_urls> for regular extensions.
540   extension = LoadManifestStrict("script_and_capture",
541       "extension_regular_all.json");
542   EXPECT_TRUE(Allowed(extension.get(), http_url));
543   EXPECT_TRUE(Allowed(extension.get(), https_url));
544   EXPECT_TRUE(CaptureOnly(extension.get(), file_url));
545   EXPECT_TRUE(CaptureOnly(extension.get(), settings_url));
546   EXPECT_TRUE(Allowed(extension.get(), favicon_url));  // chrome:// requested
547   EXPECT_TRUE(CaptureOnly(extension.get(), about_url));
548   EXPECT_TRUE(CaptureOnly(extension.get(), extension_url));
549
550   // Test access to iframed content.
551   GURL within_extension_url = extension->GetResourceURL("page.html");
552   EXPECT_TRUE(AllowedScript(extension.get(), http_url, http_url_with_path));
553   EXPECT_TRUE(AllowedScript(extension.get(), https_url, http_url_with_path));
554   EXPECT_TRUE(AllowedScript(extension.get(), http_url, within_extension_url));
555   EXPECT_TRUE(AllowedScript(extension.get(), https_url, within_extension_url));
556   EXPECT_TRUE(BlockedScript(extension.get(), http_url, extension_url));
557   EXPECT_TRUE(BlockedScript(extension.get(), https_url, extension_url));
558
559   const PermissionsData* permissions_data = extension->permissions_data();
560   EXPECT_FALSE(permissions_data->HasHostPermission(settings_url));
561   EXPECT_FALSE(permissions_data->HasHostPermission(about_url));
562   EXPECT_TRUE(permissions_data->HasHostPermission(favicon_url));
563
564   // Test * for scheme, which implies just the http/https schemes.
565   extension = LoadManifestStrict("script_and_capture",
566       "extension_wildcard.json");
567   EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
568   EXPECT_TRUE(ScriptOnly(extension.get(), https_url, https_url));
569   EXPECT_TRUE(Blocked(extension.get(), settings_url));
570   EXPECT_TRUE(Blocked(extension.get(), about_url));
571   EXPECT_TRUE(Blocked(extension.get(), file_url));
572   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
573   extension =
574       LoadManifest("script_and_capture", "extension_wildcard_settings.json");
575   EXPECT_TRUE(Blocked(extension.get(), settings_url));
576
577   // Having chrome://*/ should work for regular extensions with the flag
578   // enabled.
579   std::string error;
580   extension = LoadManifestUnchecked("script_and_capture",
581                                     "extension_wildcard_chrome.json",
582                                     Manifest::INTERNAL, Extension::NO_FLAGS,
583                                     &error);
584   EXPECT_FALSE(extension.get() == NULL);
585   EXPECT_TRUE(Blocked(extension.get(), http_url));
586   EXPECT_TRUE(Blocked(extension.get(), https_url));
587   EXPECT_TRUE(ScriptOnly(extension.get(), settings_url, settings_url));
588   EXPECT_TRUE(Blocked(extension.get(), about_url));
589   EXPECT_TRUE(Blocked(extension.get(), file_url));
590   EXPECT_TRUE(ScriptOnly(extension.get(), favicon_url, favicon_url));
591
592   // Having chrome://favicon/* should not give you chrome://*
593   extension = LoadManifestStrict("script_and_capture",
594       "extension_chrome_favicon_wildcard.json");
595   EXPECT_TRUE(Blocked(extension.get(), settings_url));
596   EXPECT_TRUE(ScriptOnly(extension.get(), favicon_url, favicon_url));
597   EXPECT_TRUE(Blocked(extension.get(), about_url));
598   EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));
599
600   // Having http://favicon should not give you chrome://favicon
601   extension = LoadManifestStrict("script_and_capture",
602       "extension_http_favicon.json");
603   EXPECT_TRUE(Blocked(extension.get(), settings_url));
604   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
605
606   // Component extensions with <all_urls> should get everything.
607   extension = LoadManifest("script_and_capture", "extension_component_all.json",
608       Manifest::COMPONENT, Extension::NO_FLAGS);
609   EXPECT_TRUE(Allowed(extension.get(), http_url));
610   EXPECT_TRUE(Allowed(extension.get(), https_url));
611   EXPECT_TRUE(Allowed(extension.get(), settings_url));
612   EXPECT_TRUE(Allowed(extension.get(), about_url));
613   EXPECT_TRUE(Allowed(extension.get(), favicon_url));
614   EXPECT_TRUE(extension->permissions_data()->HasHostPermission(favicon_url));
615
616   // Component extensions should only get access to what they ask for.
617   extension = LoadManifest("script_and_capture",
618       "extension_component_google.json", Manifest::COMPONENT,
619       Extension::NO_FLAGS);
620   EXPECT_TRUE(ScriptOnly(extension.get(), http_url, http_url));
621   EXPECT_TRUE(Blocked(extension.get(), https_url));
622   EXPECT_TRUE(Blocked(extension.get(), file_url));
623   EXPECT_TRUE(Blocked(extension.get(), settings_url));
624   EXPECT_TRUE(Blocked(extension.get(), favicon_url));
625   EXPECT_TRUE(Blocked(extension.get(), about_url));
626   EXPECT_TRUE(Blocked(extension.get(), extension_url));
627   EXPECT_FALSE(extension->permissions_data()->HasHostPermission(settings_url));
628 }
629
630 TEST_F(ExtensionScriptAndCaptureVisibleTest, TabSpecific) {
631   scoped_refptr<Extension> extension =
632       LoadManifestStrict("script_and_capture", "tab_specific.json");
633
634   const PermissionsData* permissions_data = extension->permissions_data();
635   EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0));
636   EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(1));
637   EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(2));
638
639   std::set<GURL> no_urls;
640
641   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0));
642   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1));
643   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));
644
645   URLPatternSet allowed_hosts;
646   allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
647                                       http_url.spec()));
648   std::set<GURL> allowed_urls;
649   allowed_urls.insert(http_url);
650   // http_url_with_path() will also be allowed, because Extension should be
651   // considering the security origin of the URL not the URL itself, and
652   // http_url is in allowed_hosts.
653   allowed_urls.insert(http_url_with_path);
654
655   {
656     scoped_refptr<PermissionSet> permissions(
657         new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
658                           allowed_hosts, URLPatternSet()));
659     permissions_data->UpdateTabSpecificPermissions(0, permissions);
660     EXPECT_EQ(permissions->explicit_hosts(),
661               permissions_data->GetTabSpecificPermissionsForTesting(0)
662                   ->explicit_hosts());
663   }
664
665   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
666   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1));
667   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));
668
669   permissions_data->ClearTabSpecificPermissions(0);
670   EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0));
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   std::set<GURL> more_allowed_urls = allowed_urls;
677   more_allowed_urls.insert(https_url);
678   URLPatternSet more_allowed_hosts = allowed_hosts;
679   more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
680                                            https_url.spec()));
681
682   {
683     scoped_refptr<PermissionSet> permissions(
684         new PermissionSet(APIPermissionSet(),  ManifestPermissionSet(),
685                           allowed_hosts, URLPatternSet()));
686     permissions_data->UpdateTabSpecificPermissions(0, permissions);
687     EXPECT_EQ(permissions->explicit_hosts(),
688               permissions_data->GetTabSpecificPermissionsForTesting(0)
689                   ->explicit_hosts());
690
691     permissions = new PermissionSet(APIPermissionSet(),
692                                     ManifestPermissionSet(),
693                                     more_allowed_hosts,
694                                     URLPatternSet());
695     permissions_data->UpdateTabSpecificPermissions(1, permissions);
696     EXPECT_EQ(permissions->explicit_hosts(),
697               permissions_data->GetTabSpecificPermissionsForTesting(1)
698                   ->explicit_hosts());
699   }
700
701   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), allowed_urls, 0));
702   EXPECT_TRUE(
703       ScriptAllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
704   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));
705
706   permissions_data->ClearTabSpecificPermissions(0);
707   EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(0));
708
709   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0));
710   EXPECT_TRUE(
711       ScriptAllowedExclusivelyOnTab(extension.get(), more_allowed_urls, 1));
712   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));
713
714   permissions_data->ClearTabSpecificPermissions(1);
715   EXPECT_FALSE(permissions_data->GetTabSpecificPermissionsForTesting(1));
716
717   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 0));
718   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 1));
719   EXPECT_TRUE(ScriptAllowedExclusivelyOnTab(extension.get(), no_urls, 2));
720 }
721
722 }  // namespace extensions