Commit 58ef1088 authored by Karan Bhatia's avatar Karan Bhatia Committed by Commit Bot

Extensions: Add more test coverage for extensions ability to xhr file urls.

This CL adds more test coverage for an extensions ability to xhr file urls
through an extension frame. To XHR a file url an extension should have "Allow
access to file URLs" setting enabled and also have host permissions to file:///.
Tests are also added for activeTab.

This also helps discover a bug with the network service implementation of the
same.

BUG=816685

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: Ic53a1ad9c25a5db56c69eb421734f76ba9f95a1e
Reviewed-on: https://chromium-review.googlesource.com/985798Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547551}
parent aa59e87c
...@@ -7,13 +7,19 @@ ...@@ -7,13 +7,19 @@
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/extensions/extension_action_runner.h" #include "chrome/browser/extensions/extension_action_runner.h"
#include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "extensions/test/extension_test_message_listener.h" #include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h" #include "extensions/test/result_catcher.h"
#include "net/base/filename_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -93,5 +99,95 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ActiveTab) { ...@@ -93,5 +99,95 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ActiveTab) {
} }
} }
// Tests the behavior of activeTab and its relation to an extension's ability to
// xhr file urls.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, XHRFileURLs) {
ASSERT_TRUE(StartEmbeddedTestServer());
ExtensionTestMessageListener background_page_ready("ready",
false /*will_reply*/);
const Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("active_tab_file_urls"));
ASSERT_TRUE(extension);
const std::string extension_id = extension->id();
// Ensure the extension's background page is ready.
EXPECT_TRUE(background_page_ready.WaitUntilSatisfied());
auto can_xhr_file_urls = [this, &extension_id]() {
constexpr char script[] = R"(
var req = new XMLHttpRequest();
var url = '%s';
req.open('GET', url, true);
req.onload = function() {
if (req.responseText === 'Hello!')
window.domAutomationController.send('true');
};
// We track 'onloadend' to detect failures instead of 'onerror', since for
// access check violations 'abort' event may be raised (instead of the
// 'error' event).
req.onloadend = function() {
if (req.status === 0)
window.domAutomationController.send('false');
};
req.send();
)";
base::FilePath test_file =
test_data_dir_.DirName().AppendASCII("test_file.txt");
std::string result = ExecuteScriptInBackgroundPage(
extension_id,
base::StringPrintf(script,
net::FilePathToFileURL(test_file).spec().c_str()));
EXPECT_TRUE(result == "true" || result == "false");
return result == "true";
};
// By default the extension should have file access enabled. However, since it
// does not have host permissions to the localhost on the file scheme, it
// should not be able to xhr file urls.
EXPECT_TRUE(util::AllowFileAccess(extension_id, profile()));
EXPECT_FALSE(can_xhr_file_urls());
// Navigate to a file url (the extension's manifest.json in this case).
GURL manifest_file_url =
net::FilePathToFileURL(extension->path().AppendASCII("manifest.json"));
ui_test_utils::NavigateToURL(browser(), manifest_file_url);
// First don't grant the tab permission. Verify that the extension can't xhr
// file urls.
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
ExtensionActionRunner::GetForWebContents(web_contents)
->RunAction(extension, false /*grant_tab_permissions*/);
EXPECT_FALSE(can_xhr_file_urls());
// Now grant the tab permission. Ensure the extension can now xhr file urls.
ExtensionActionRunner::GetForWebContents(web_contents)
->RunAction(extension, true /*grant_tab_permissions*/);
EXPECT_TRUE(can_xhr_file_urls());
// Revoke extension's access to file urls. This will cause the extension to
// reload, invalidating the |extension| pointer. Re-initialize the |extension|
// pointer.
background_page_ready.Reset();
util::SetAllowFileAccess(extension_id, profile(), false /*allow*/);
EXPECT_FALSE(util::AllowFileAccess(extension_id, profile()));
extension = TestExtensionRegistryObserver(ExtensionRegistry::Get(profile()))
.WaitForExtensionLoaded();
EXPECT_TRUE(extension);
// Ensure the extension's background page is ready.
EXPECT_TRUE(background_page_ready.WaitUntilSatisfied());
// Grant the tab permission for the active url to the extension. Ensure it
// still can't xhr file urls (since it does not have file access).
ExtensionActionRunner::GetForWebContents(web_contents)
->RunAction(extension, true /*grant_tab_permissions*/);
EXPECT_FALSE(can_xhr_file_urls());
}
} // namespace } // namespace
} // namespace extensions } // namespace extensions
...@@ -31,11 +31,24 @@ IN_PROC_BROWSER_TEST_F(CrossOriginXHR, ContentScript) { ...@@ -31,11 +31,24 @@ IN_PROC_BROWSER_TEST_F(CrossOriginXHR, ContentScript) {
ASSERT_TRUE(RunExtensionTest("cross_origin_xhr/content_script")) << message_; ASSERT_TRUE(RunExtensionTest("cross_origin_xhr/content_script")) << message_;
} }
IN_PROC_BROWSER_TEST_F(CrossOriginXHR, FileAccess) { // Tests that an extension frame can xhr a file url if it has file access and
ASSERT_TRUE(RunExtensionTest("cross_origin_xhr/file_access")) << message_; // "<all_urls>" host permissions.
IN_PROC_BROWSER_TEST_F(CrossOriginXHR, FileAccessAllURLs) {
ASSERT_TRUE(RunExtensionTest("cross_origin_xhr/file_access_all_urls"))
<< message_;
} }
IN_PROC_BROWSER_TEST_F(CrossOriginXHR, NoFileAccess) { // Tests that an extension frame can't xhr a file url if it has no file access
ASSERT_TRUE(RunExtensionTestNoFileAccess( // even with the "<all_urls>" host permissions.
"cross_origin_xhr/no_file_access")) << message_; IN_PROC_BROWSER_TEST_F(CrossOriginXHR, NoFileAccessAllURLs) {
ASSERT_TRUE(
RunExtensionTestNoFileAccess("cross_origin_xhr/no_file_access_all_urls"))
<< message_;
}
// Tests that an extension frame can't xhr a file url if it does not have host
// permissions to the file scheme even though it has file access.
IN_PROC_BROWSER_TEST_F(CrossOriginXHR, FileAccessNoHosts) {
ASSERT_TRUE(RunExtensionTest("cross_origin_xhr/file_access_no_hosts"))
<< message_;
} }
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
chrome.test.sendMessage('ready');
{
"manifest_version": 2,
"name": "Test xhr to file urls with activeTab",
"version": "1.0",
"browser_action": {
"default_title": "activeTab"
},
"background" : {
"scripts" : ["background.js"]
},
"permissions": [
"activeTab"
]
}
{
"name": "Cross origin XHR to file:/// URLs with no host permissions",
"version": "1.0",
"manifest_version": 2,
"background": {
"scripts": ["test.js"]
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
chrome.test.getConfig(function(config) {
chrome.test.runTests([
function fileAccessNotAllowed() {
var req = new XMLHttpRequest();
var url = config.testDataDirectory + '/../test_file.txt';
chrome.test.log('Requesting url: ' + url);
req.open('GET', url, true);
req.onload = function() {
chrome.test.fail('Unexpected success for url: ' + url);
}
req.onerror = function() {
chrome.test.assertEq(0, req.status);
chrome.test.succeed();
}
req.send(null);
}
]);
});
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
-ExpectCTBrowserTest.TestDynamicExpectCTHeaderProcessing -ExpectCTBrowserTest.TestDynamicExpectCTHeaderProcessing
-ExpectCTBrowserTest.TestDynamicExpectCTReporting -ExpectCTBrowserTest.TestDynamicExpectCTReporting
-ExtensionApiTest.Debugger -ExtensionApiTest.Debugger
-ExtensionApiTest.XHRFileURLs
-ExtensionApiTestWithSwitch.ExtensionDebugger -ExtensionApiTestWithSwitch.ExtensionDebugger
-ExtensionUnloadBrowserTest.UnloadWithContentScripts -ExtensionUnloadBrowserTest.UnloadWithContentScripts
-LocalNTPVoiceJavascriptTest.TextTests -LocalNTPVoiceJavascriptTest.TextTests
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment