Commit 8a5d9397 authored by Paul Miller's avatar Paul Miller Committed by Commit Bot

Allow non-WebUI navigations in single-process mode

WebUINavigationThrottle blocks WebUI (chrome://...) pages from loading
non-WebUI pages in subframes.

When a renderer navigates to a WebUI page, a "WebUI bindings" bit is set
in that renderer's ChildProcessSecurityPolicyImpl::SecurityState, and it
remains for the lifetime of the renderer process.
WebUINavigationThrottles are created for renderers with this bit set.

In multi-process mode, navigating away from the WebUI page creates a
fresh renderer with a fresh SecurityState, so subsequent non-WebUI pages
are again able to load non-WebUI subframes.

In single-process mode, the WebUI bit remains. After visiting a WebUI
page, iframes on all other pages will be broken until Chrome is
restarted.

This breaks Android WebView as well, since WebView uses single-process
on old Android versions and low-memory devices. It breaks CTS because
testOnSafeBrowsingHit loads chrome://safe-browsing/match?type=malware,
which sets the bit, and then testShouldOverrideUrlLoadingOnCreateWindow
tries to use an iframe.

Fix this by not creating a WebUINavigationThrottle in single-process
mode.

BUG=924799

Change-Id: I5a61f45dc065681f0e6b97e0b205e804edbd7402
Reviewed-on: https://chromium-review.googlesource.com/c/1432953
Commit-Queue: Paul Miller <paulmiller@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#626267}
parent 9e49f6a7
......@@ -4,10 +4,12 @@
#include "content/browser/frame_host/webui_navigation_throttle.h"
#include "base/command_line.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
namespace content {
......@@ -35,7 +37,13 @@ const char* WebUINavigationThrottle::GetNameForLogging() {
std::unique_ptr<NavigationThrottle>
WebUINavigationThrottle::CreateThrottleForNavigation(
NavigationHandle* navigation_handle) {
// Create the throttle only for subframe navigations.
// The WebUI security model (which keeps renderes with WebUI bindings separate
// from untrusted renderers) only makes sense in multi-process mode.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSingleProcess))
return nullptr;
// Only throttle subframe navigations.
if (navigation_handle->IsInMainFrame())
return nullptr;
......@@ -45,8 +53,8 @@ WebUINavigationThrottle::CreateThrottleForNavigation(
->parent()
->current_frame_host();
// Create a throttle only for navigations where the parent frame is either
// at a chrome:// URL or is in a process with WebUI bindings.
// Throttle if the renderer process has WebUI bindings, or if the parent frame
// is on a WebUI page.
if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
parent->GetProcess()->GetID()) ||
parent->GetLastCommittedURL().SchemeIs(kChromeUIScheme)) {
......
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