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