blob: 20acc0de48ec388726b6ae47b1df1e4e0dfe5fbc [file] [log] [blame]
[email protected]78cd68e2014-05-22 20:33:521// Copyright 2014 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 <map>
6
7#include "base/values.h"
8#include "chrome/browser/extensions/active_script_controller.h"
9#include "chrome/browser/extensions/active_tab_permission_granter.h"
rdevlin.cronin699ca6ff2014-09-29 23:59:5710#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
[email protected]b33c8c22014-05-29 19:51:0811#include "chrome/browser/extensions/extension_util.h"
[email protected]23a85362014-07-07 23:26:1912#include "chrome/browser/extensions/permissions_updater.h"
[email protected]78cd68e2014-05-22 20:33:5213#include "chrome/browser/extensions/tab_helper.h"
14#include "chrome/test/base/chrome_render_view_host_test_harness.h"
15#include "chrome/test/base/testing_profile.h"
[email protected]fdd28372014-08-21 02:27:2616#include "components/crx_file/id_util.h"
[email protected]78cd68e2014-05-22 20:33:5217#include "content/public/browser/navigation_controller.h"
18#include "content/public/browser/navigation_entry.h"
19#include "content/public/browser/web_contents.h"
20#include "extensions/browser/extension_registry.h"
21#include "extensions/common/extension.h"
22#include "extensions/common/extension_builder.h"
23#include "extensions/common/feature_switch.h"
[email protected]78cd68e2014-05-22 20:33:5224#include "extensions/common/manifest.h"
[email protected]23a85362014-07-07 23:26:1925#include "extensions/common/user_script.h"
[email protected]78cd68e2014-05-22 20:33:5226#include "extensions/common/value_builder.h"
27
28namespace extensions {
29
30namespace {
31
32const char kAllHostsPermission[] = "*://*/*";
33
34} // namespace
35
36// Unittests for the ActiveScriptController mostly test the internal logic
37// of the controller itself (when to allow/deny extension script injection).
38// Testing real injection is allowed/denied as expected (i.e., that the
39// ActiveScriptController correctly interfaces in the system) is done in the
40// ActiveScriptControllerBrowserTests.
41class ActiveScriptControllerUnitTest : public ChromeRenderViewHostTestHarness {
42 protected:
43 ActiveScriptControllerUnitTest();
44 virtual ~ActiveScriptControllerUnitTest();
45
46 // Creates an extension with all hosts permission and adds it to the registry.
47 const Extension* AddExtension();
48
[email protected]e1670582014-08-15 23:05:4149 // Reloads |extension_| by removing it from the registry and recreating it.
50 const Extension* ReloadExtension();
51
[email protected]23a85362014-07-07 23:26:1952 // Returns true if the |extension| requires user consent before injecting
53 // a script.
54 bool RequiresUserConsent(const Extension* extension) const;
55
56 // Request an injection for the given |extension|.
57 void RequestInjection(const Extension* extension);
[email protected]78cd68e2014-05-22 20:33:5258
59 // Returns the number of times a given extension has had a script execute.
60 size_t GetExecutionCountForExtension(const std::string& extension_id) const;
61
[email protected]23a85362014-07-07 23:26:1962 ActiveScriptController* controller() const {
63 return active_script_controller_;
64 }
[email protected]78cd68e2014-05-22 20:33:5265
66 private:
[email protected]23a85362014-07-07 23:26:1967 // Returns a closure to use as a script execution for a given extension.
68 base::Closure GetExecutionCallbackForExtension(
69 const std::string& extension_id);
70
[email protected]78cd68e2014-05-22 20:33:5271 // Increment the number of executions for the given |extension_id|.
72 void IncrementExecutionCount(const std::string& extension_id);
73
74 virtual void SetUp() OVERRIDE;
75
76 // Since ActiveScriptController's behavior is behind a flag, override the
77 // feature switch.
78 FeatureSwitch::ScopedOverride feature_override_;
79
80 // The associated ActiveScriptController.
81 ActiveScriptController* active_script_controller_;
82
83 // The map of observed executions, keyed by extension id.
84 std::map<std::string, int> extension_executions_;
[email protected]e1670582014-08-15 23:05:4185
86 scoped_refptr<const Extension> extension_;
[email protected]78cd68e2014-05-22 20:33:5287};
88
89ActiveScriptControllerUnitTest::ActiveScriptControllerUnitTest()
90 : feature_override_(FeatureSwitch::scripts_require_action(),
91 FeatureSwitch::OVERRIDE_ENABLED),
92 active_script_controller_(NULL) {
93}
94
95ActiveScriptControllerUnitTest::~ActiveScriptControllerUnitTest() {
96}
97
98const Extension* ActiveScriptControllerUnitTest::AddExtension() {
[email protected]fdd28372014-08-21 02:27:2699 const std::string kId = crx_file::id_util::GenerateId("all_hosts_extension");
[email protected]e1670582014-08-15 23:05:41100 extension_ = ExtensionBuilder()
101 .SetManifest(
102 DictionaryBuilder()
103 .Set("name", "all_hosts_extension")
104 .Set("description", "an extension")
105 .Set("manifest_version", 2)
106 .Set("version", "1.0.0")
107 .Set("permissions",
108 ListBuilder().Append(kAllHostsPermission)))
109 .SetLocation(Manifest::INTERNAL)
110 .SetID(kId)
111 .Build();
[email protected]78cd68e2014-05-22 20:33:52112
[email protected]e1670582014-08-15 23:05:41113 ExtensionRegistry::Get(profile())->AddEnabled(extension_);
dchengc7047942014-08-26 05:05:31114 PermissionsUpdater(profile()).InitializePermissions(extension_.get());
115 return extension_.get();
[email protected]e1670582014-08-15 23:05:41116}
117
118const Extension* ActiveScriptControllerUnitTest::ReloadExtension() {
119 ExtensionRegistry::Get(profile())->RemoveEnabled(extension_->id());
120 return AddExtension();
[email protected]78cd68e2014-05-22 20:33:52121}
122
[email protected]23a85362014-07-07 23:26:19123bool ActiveScriptControllerUnitTest::RequiresUserConsent(
124 const Extension* extension) const {
125 PermissionsData::AccessType access_type =
126 controller()->RequiresUserConsentForScriptInjectionForTesting(
127 extension, UserScript::PROGRAMMATIC_SCRIPT);
128 // We should never downright refuse access in these tests.
129 DCHECK_NE(PermissionsData::ACCESS_DENIED, access_type);
130 return access_type == PermissionsData::ACCESS_WITHHELD;
131}
132
133void ActiveScriptControllerUnitTest::RequestInjection(
134 const Extension* extension) {
135 controller()->RequestScriptInjectionForTesting(
136 extension,
137 GetExecutionCallbackForExtension(extension->id()));
[email protected]78cd68e2014-05-22 20:33:52138}
139
140size_t ActiveScriptControllerUnitTest::GetExecutionCountForExtension(
141 const std::string& extension_id) const {
142 std::map<std::string, int>::const_iterator iter =
143 extension_executions_.find(extension_id);
144 if (iter != extension_executions_.end())
145 return iter->second;
146 return 0u;
147}
148
[email protected]23a85362014-07-07 23:26:19149base::Closure ActiveScriptControllerUnitTest::GetExecutionCallbackForExtension(
150 const std::string& extension_id) {
151 // We use base unretained here, but if this ever gets executed outside of
152 // this test's lifetime, we have a major problem anyway.
153 return base::Bind(&ActiveScriptControllerUnitTest::IncrementExecutionCount,
154 base::Unretained(this),
155 extension_id);
156}
157
[email protected]78cd68e2014-05-22 20:33:52158void ActiveScriptControllerUnitTest::IncrementExecutionCount(
159 const std::string& extension_id) {
160 ++extension_executions_[extension_id];
161}
162
163void ActiveScriptControllerUnitTest::SetUp() {
164 ChromeRenderViewHostTestHarness::SetUp();
165
166 TabHelper::CreateForWebContents(web_contents());
167 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents());
rdevlin.cronin91f162a12014-09-03 16:48:40168 // These should never be NULL.
[email protected]78cd68e2014-05-22 20:33:52169 DCHECK(tab_helper);
rdevlin.cronin91f162a12014-09-03 16:48:40170 active_script_controller_ = tab_helper->active_script_controller();
[email protected]78cd68e2014-05-22 20:33:52171 DCHECK(active_script_controller_);
172}
173
174// Test that extensions with all_hosts require permission to execute, and, once
175// that permission is granted, do execute.
176TEST_F(ActiveScriptControllerUnitTest, RequestPermissionAndExecute) {
177 const Extension* extension = AddExtension();
178 ASSERT_TRUE(extension);
179
180 NavigateAndCommit(GURL("https://www.google.com"));
181
182 // Ensure that there aren't any executions pending.
183 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40184 ASSERT_FALSE(controller()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52185
rdevlin.cronin699ca6ff2014-09-29 23:59:57186 ExtensionActionAPI* extension_action_api =
187 ExtensionActionAPI::Get(profile());
188 ASSERT_FALSE(extension_action_api->ExtensionWantsToRun(extension,
189 web_contents()));
190
[email protected]78cd68e2014-05-22 20:33:52191 // Since the extension requests all_hosts, we should require user consent.
[email protected]23a85362014-07-07 23:26:19192 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52193
rdevlin.cronin91f162a12014-09-03 16:48:40194 // Request an injection. The extension should want to run, but should not have
195 // executed.
[email protected]23a85362014-07-07 23:26:19196 RequestInjection(extension);
rdevlin.cronin91f162a12014-09-03 16:48:40197 EXPECT_TRUE(controller()->WantsToRun(extension));
rdevlin.cronin699ca6ff2014-09-29 23:59:57198 EXPECT_TRUE(extension_action_api->ExtensionWantsToRun(extension,
199 web_contents()));
[email protected]78cd68e2014-05-22 20:33:52200 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
201
202 // Click to accept the extension executing.
203 controller()->OnClicked(extension);
204
rdevlin.cronin91f162a12014-09-03 16:48:40205 // The extension should execute, and the extension shouldn't want to run.
[email protected]78cd68e2014-05-22 20:33:52206 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40207 EXPECT_FALSE(controller()->WantsToRun(extension));
rdevlin.cronin699ca6ff2014-09-29 23:59:57208 EXPECT_FALSE(extension_action_api->ExtensionWantsToRun(extension,
209 web_contents()));
[email protected]78cd68e2014-05-22 20:33:52210
211 // Since we already executed on the given page, we shouldn't need permission
212 // for a second time.
[email protected]23a85362014-07-07 23:26:19213 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52214
[email protected]4b8d1c62014-08-16 01:22:21215 // Reloading and same-origin navigations shouldn't clear those permissions,
216 // and we shouldn't require user constent again.
[email protected]78cd68e2014-05-22 20:33:52217 Reload();
[email protected]4b8d1c62014-08-16 01:22:21218 EXPECT_FALSE(RequiresUserConsent(extension));
219 NavigateAndCommit(GURL("https://www.google.com/foo"));
220 EXPECT_FALSE(RequiresUserConsent(extension));
221 NavigateAndCommit(GURL("https://www.google.com/bar"));
222 EXPECT_FALSE(RequiresUserConsent(extension));
223
224 // Cross-origin navigations should clear permissions.
225 NavigateAndCommit(GURL("https://otherdomain.google.com"));
[email protected]23a85362014-07-07 23:26:19226 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52227
228 // Grant access.
[email protected]23a85362014-07-07 23:26:19229 RequestInjection(extension);
[email protected]78cd68e2014-05-22 20:33:52230 controller()->OnClicked(extension);
231 EXPECT_EQ(2u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40232 EXPECT_FALSE(controller()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52233
234 // Navigating to another site should also clear the permissions.
235 NavigateAndCommit(GURL("https://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19236 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52237}
238
239// Test that injections that are not executed by the time the user navigates are
240// ignored and never execute.
241TEST_F(ActiveScriptControllerUnitTest, PendingInjectionsRemovedAtNavigation) {
242 const Extension* extension = AddExtension();
243 ASSERT_TRUE(extension);
244
245 NavigateAndCommit(GURL("https://www.google.com"));
246
247 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
248
rdevlin.cronin91f162a12014-09-03 16:48:40249 // Request an injection. The extension should want to run, but not execute.
[email protected]23a85362014-07-07 23:26:19250 RequestInjection(extension);
rdevlin.cronin91f162a12014-09-03 16:48:40251 EXPECT_TRUE(controller()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52252 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
253
[email protected]8d5cb212014-06-04 09:00:39254 // Reload. This should remove the pending injection, and we should not
[email protected]78cd68e2014-05-22 20:33:52255 // execute anything.
[email protected]8d5cb212014-06-04 09:00:39256 Reload();
rdevlin.cronin91f162a12014-09-03 16:48:40257 EXPECT_FALSE(controller()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52258 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
259
260 // Request and accept a new injection.
[email protected]23a85362014-07-07 23:26:19261 RequestInjection(extension);
[email protected]78cd68e2014-05-22 20:33:52262 controller()->OnClicked(extension);
263
264 // The extension should only have executed once, even though a grand total
265 // of two executions were requested.
266 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40267 EXPECT_FALSE(controller()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52268}
269
270// Test that queueing multiple pending injections, and then accepting, triggers
271// them all.
272TEST_F(ActiveScriptControllerUnitTest, MultiplePendingInjection) {
273 const Extension* extension = AddExtension();
274 ASSERT_TRUE(extension);
275 NavigateAndCommit(GURL("https://www.google.com"));
276
277 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
278
279 const size_t kNumInjections = 3u;
280 // Queue multiple pending injections.
[email protected]23a85362014-07-07 23:26:19281 for (size_t i = 0u; i < kNumInjections; ++i)
282 RequestInjection(extension);
283
[email protected]78cd68e2014-05-22 20:33:52284 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
285
286 controller()->OnClicked(extension);
287
288 // All pending injections should have executed.
289 EXPECT_EQ(kNumInjections, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40290 EXPECT_FALSE(controller()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52291}
292
293TEST_F(ActiveScriptControllerUnitTest, ActiveScriptsUseActiveTabPermissions) {
294 const Extension* extension = AddExtension();
295 NavigateAndCommit(GURL("https://www.google.com"));
296
297 ActiveTabPermissionGranter* active_tab_permission_granter =
298 TabHelper::FromWebContents(web_contents())
299 ->active_tab_permission_granter();
300 ASSERT_TRUE(active_tab_permission_granter);
301 // Grant the extension active tab permissions. This normally happens, e.g.,
302 // if the user clicks on a browser action.
303 active_tab_permission_granter->GrantIfRequested(extension);
304
305 // Since we have active tab permissions, we shouldn't need user consent
306 // anymore.
[email protected]23a85362014-07-07 23:26:19307 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]78cd68e2014-05-22 20:33:52308
[email protected]4b8d1c62014-08-16 01:22:21309 // Reloading and other same-origin navigations maintain the permission to
310 // execute.
[email protected]8d5cb212014-06-04 09:00:39311 Reload();
[email protected]4b8d1c62014-08-16 01:22:21312 EXPECT_FALSE(RequiresUserConsent(extension));
313 NavigateAndCommit(GURL("https://www.google.com/foo"));
314 EXPECT_FALSE(RequiresUserConsent(extension));
315 NavigateAndCommit(GURL("https://www.google.com/bar"));
316 EXPECT_FALSE(RequiresUserConsent(extension));
317
318 // Navigating to a different origin will require user consent again.
319 NavigateAndCommit(GURL("https://yahoo.com"));
320 EXPECT_TRUE(RequiresUserConsent(extension));
321
322 // Back to the original origin should also re-require constent.
323 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19324 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]11814f52014-05-23 06:50:35325
[email protected]23a85362014-07-07 23:26:19326 RequestInjection(extension);
rdevlin.cronin91f162a12014-09-03 16:48:40327 EXPECT_TRUE(controller()->WantsToRun(extension));
[email protected]11814f52014-05-23 06:50:35328 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
329
330 // Grant active tab.
331 active_tab_permission_granter->GrantIfRequested(extension);
332
333 // The pending injections should have run since active tab permission was
334 // granted.
335 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40336 EXPECT_FALSE(controller()->WantsToRun(extension));
[email protected]78cd68e2014-05-22 20:33:52337}
338
[email protected]b33c8c22014-05-29 19:51:08339TEST_F(ActiveScriptControllerUnitTest, ActiveScriptsCanHaveAllUrlsPref) {
340 const Extension* extension = AddExtension();
341 ASSERT_TRUE(extension);
342
343 NavigateAndCommit(GURL("https://www.google.com"));
[email protected]23a85362014-07-07 23:26:19344 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08345
346 // Enable the extension on all urls.
347 util::SetAllowedScriptingOnAllUrls(extension->id(), profile(), true);
348
[email protected]23a85362014-07-07 23:26:19349 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08350 // This should carry across navigations, and websites.
351 NavigateAndCommit(GURL("http://www.foo.com"));
[email protected]23a85362014-07-07 23:26:19352 EXPECT_FALSE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08353
354 // Turning off the preference should have instant effect.
355 util::SetAllowedScriptingOnAllUrls(extension->id(), profile(), false);
[email protected]23a85362014-07-07 23:26:19356 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08357
358 // And should also persist across navigations and websites.
359 NavigateAndCommit(GURL("http://www.bar.com"));
[email protected]23a85362014-07-07 23:26:19360 EXPECT_TRUE(RequiresUserConsent(extension));
[email protected]b33c8c22014-05-29 19:51:08361}
362
[email protected]e1670582014-08-15 23:05:41363TEST_F(ActiveScriptControllerUnitTest, TestAlwaysRun) {
364 const Extension* extension = AddExtension();
365 ASSERT_TRUE(extension);
366
367 NavigateAndCommit(GURL("https://www.google.com/?gws_rd=ssl"));
368
369 // Ensure that there aren't any executions pending.
370 ASSERT_EQ(0u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40371 ASSERT_FALSE(controller()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41372
373 // Since the extension requests all_hosts, we should require user consent.
374 EXPECT_TRUE(RequiresUserConsent(extension));
375
rdevlin.cronin91f162a12014-09-03 16:48:40376 // Request an injection. The extension should want to run, but not execute.
[email protected]e1670582014-08-15 23:05:41377 RequestInjection(extension);
rdevlin.cronin91f162a12014-09-03 16:48:40378 EXPECT_TRUE(controller()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41379 EXPECT_EQ(0u, GetExecutionCountForExtension(extension->id()));
380
381 // Allow the extension to always run on this origin.
382 controller()->AlwaysRunOnVisibleOrigin(extension);
383
rdevlin.cronin91f162a12014-09-03 16:48:40384 // The extension should execute, and the extension shouldn't want to run.
[email protected]e1670582014-08-15 23:05:41385 EXPECT_EQ(1u, GetExecutionCountForExtension(extension->id()));
rdevlin.cronin91f162a12014-09-03 16:48:40386 EXPECT_FALSE(controller()->WantsToRun(extension));
[email protected]e1670582014-08-15 23:05:41387
388 // Since we already executed on the given page, we shouldn't need permission
389 // for a second time.
390 EXPECT_FALSE(RequiresUserConsent(extension));
391
392 // Navigating to another site that hasn't been granted a persisted permission
393 // should necessitate user consent.
394 NavigateAndCommit(GURL("https://www.foo.com/bar"));
395 EXPECT_TRUE(RequiresUserConsent(extension));
396
397 // We shouldn't need user permission upon returning to the original origin.
398 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
399 EXPECT_FALSE(RequiresUserConsent(extension));
400
401 // Reloading the extension should not clear any granted host permissions.
402 extension = ReloadExtension();
403 Reload();
404 EXPECT_FALSE(RequiresUserConsent(extension));
405
406 // Different host...
407 NavigateAndCommit(GURL("https://www.foo.com/bar"));
408 EXPECT_TRUE(RequiresUserConsent(extension));
409 // Different scheme...
410 NavigateAndCommit(GURL("http://www.google.com/foo/bar"));
411 EXPECT_TRUE(RequiresUserConsent(extension));
412 // Different subdomain...
413 NavigateAndCommit(GURL("https://en.google.com/foo/bar"));
414 EXPECT_TRUE(RequiresUserConsent(extension));
415 // Only the "always run" origin should be allowed to run without user consent.
416 NavigateAndCommit(GURL("https://www.google.com/foo/bar"));
417 EXPECT_FALSE(RequiresUserConsent(extension));
418}
419
[email protected]78cd68e2014-05-22 20:33:52420} // namespace extensions