chromium/chrome/browser/extensions/process_manager_browsertest.cc

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include <stddef.h>

#include <memory>
#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/extensions/extension_action_test_helper.h"
#include "chrome/browser/ui/javascript_dialogs/chrome_javascript_app_modal_dialog_view_factory.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "components/javascript_dialogs/app_modal_dialog_manager.h"
#include "components/permissions/permission_request_manager.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/browsertest_util.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/test/extension_background_page_waiter.h"
#include "extensions/test/test_extension_dir.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/origin.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_switches.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#endif

namespace extensions {

namespace {

GURL CreateBlobURL(content::RenderFrameHost* frame,
                   const std::string& content) {}

GURL CreateFileSystemURL(content::RenderFrameHost* frame,
                         const std::string& content) {}

std::string GetTextContent(content::RenderFrameHost* frame) {}

// Helper to send a postMessage from |sender| to |opener| via window.opener,
// wait for a reply, and verify the response.  Defines its own message event
// handlers.
void VerifyPostMessageToOpener(content::RenderFrameHost* sender,
                               content::RenderFrameHost* opener) {}

// Takes a snapshot of all frames upon construction. When Wait() is called, a
// MessageLoop is created and Quit when all previously recorded frames are
// either present in the tab, or deleted. If a navigation happens between the
// construction and the Wait() call, then this logic ensures that all obsolete
// RenderFrameHosts have been destructed when Wait() returns.
// See also the comment at ProcessManagerBrowserTest::NavigateToURL.
class NavigationCompletedObserver : public content::WebContentsObserver {};

// Exists as a browser test because ExtensionHosts are hard to create without
// a real browser.
class ProcessManagerBrowserTest : public ExtensionBrowserTest {};

class DefaultProfileExtensionBrowserTest : public ExtensionBrowserTest {};

}  // namespace

// By default, no extension hosts should be present in the profile;
// they should only be present if non-component extensions are loaded
// or if the user takes some action to trigger a component extension.
// TODO(achuith): Expand this testing to include more in-depth
// testing for the signin profile, where we explicitly disallow all
// extension hosts unless it's the off-the-record profile.
IN_PROC_BROWSER_TEST_F(DefaultProfileExtensionBrowserTest, NoExtensionHosts) {}

// Test that basic extension loading creates the appropriate ExtensionHosts
// and background pages.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       ExtensionHostCreation) {}

// Test that loading an extension with a browser action does not create a
// background page and that clicking on the action creates the appropriate
// ExtensionHost.
// TODO(http://crbug.com/1271329): Times out frequently on Lacros.
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#define MAYBE_PopupHostCreation
#else
#define MAYBE_PopupHostCreation
#endif
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, MAYBE_PopupHostCreation) {}

// Content loaded from http://hlogonemlfkgpejgnedahbkiabcdhnnn should not
// interact with an installed extension with that ID. Regression test
// for bug 357382.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, HttpHostMatchingExtensionId) {}

IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, NoBackgroundPage) {}

// Tests whether frames are correctly classified. Non-extension frames should
// never appear in the list. Top-level extension frames should always appear.
// Child extension frames should only appear if it is hosted in an extension
// process (i.e. if the top-level frame is an extension page, or if OOP frames
// are enabled for extensions).
// Disabled due to flake: https://crbug.com/693287.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       DISABLED_FrameClassification) {}

// Verify correct keepalive count behavior on network request events.
// Regression test for http://crbug.com/535716.
// Disabled on Linux for flakiness: http://crbug.com/1030435.
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_KeepaliveOnNetworkRequest
#else
#define MAYBE_KeepaliveOnNetworkRequest
#endif
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       MAYBE_KeepaliveOnNetworkRequest) {}

IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, ExtensionProcessReuse) {}

// Test that navigations to blob: URLs with extension origins are disallowed
// when initiated from non-extension processes.  See https://crbug.com/645028
// and https://crbug.com/644426.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       NestedURLNavigationsToExtensionBlocked) {}

// Check that browser-side restrictions on extension blob URLs allow
// navigations that will result in downloads.  See https://crbug.com/714373.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       BlobURLDownloadsToExtensionAllowed) {}

// Test that navigations to blob: URLs with extension origins  are disallowed
// in subframes when initiated from non-extension processes, even when the main
// frame lies about its origin.  See https://crbug.com/836858.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       NestedURLNavigationsToExtensionBlockedInSubframe) {}

// Test that navigations to blob: and filesystem: URLs with extension origins
// are allowed when initiated from extension processes.  See
// https://crbug.com/645028 and https://crbug.com/644426.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       NestedURLNavigationsToExtensionAllowed) {}

// Test that navigations to blob: and filesystem: URLs with extension origins
// are disallowed in an unprivileged, non-guest web process when the extension
// origin corresponds to a Chrome app with the "webview" permission.  See
// https://crbug.com/656752.  These requests should still be allowed inside
// actual <webview> guest processes created by a Chrome app; this is checked in
// WebViewTest.Shim_TestBlobURL.
// TODO(alexmos): Enable this test once checks are implemented in the
// extensions NavigationThrottle. See https://crbug.com/919194.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       DISABLED_NestedURLNavigationsToAppBlocked) {}

// Test that a web frame can't navigate a proxy for an extension frame to a
// blob/filesystem extension URL.  See https://crbug.com/656752.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       NestedURLNavigationsViaProxyBlocked) {}

// TODO(crbug.com/41428657): This test is flaky everywhere.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       DISABLED_NestedURLNavigationsViaNoOpenerPopupBlocked) {}

IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       ServerRedirectToNonWebAccessibleResource) {}

IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       CrossExtensionEmbeddingOfWebAccessibleResources) {}

// Verify that a web popup created via window.open from an extension page can
// communicate with the extension page via window.opener.  See
// https://crbug.com/590068.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       WebPopupFromExtensionMainFrameHasValidOpener) {}

// Verify that a web popup created via window.open from an extension subframe
// can communicate with the extension page via window.opener.  Similar to the
// test above, but for subframes.  See https://crbug.com/590068.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       WebPopupFromExtensionSubframeHasValidOpener) {}

// Test that when a web site has an extension iframe, navigating that iframe to
// a different web site without --site-per-process will place it in the parent
// frame's process.  See https://crbug.com/711006.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       ExtensionFrameNavigatesToParentSiteInstance) {}

// Verify that web iframes on extension frames do not attempt to aggressively
// reuse existing processes for the same site.  This helps prevent a
// misbehaving web iframe on an extension from slowing down other processes.
// See https://crbug.com/899418.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       WebSubframeOnExtensionDoesNotReuseExistingProcess) {}

// Test to verify that loading a resource other than an icon file is
// disallowed for hosted apps, while icons are allowed.
// See https://crbug.com/717626.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, HostedAppFilesAccess) {}

// Tests that we correctly account for vanilla web URLs that may be in the
// same SiteInstance as a hosted app, and display alerts correctly.
// https://crbug.com/746517.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, HostedAppAlerts) {}

// Tests retrieving a context ID for a given extension's service worker.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, GetWorkerContextId) {}

// Basic test to checks that service worker keepalives are tracked properly in
// the ProcessManager.
IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
                       ActiveServiceWorkerKeepalivesAreTracked) {}

}  // namespace extensions