summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2018-04-27 00:12:08 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2018-08-20 09:25:32 +0000
commitd739b9e990b1c2daff4d47c810ac3e256af385c8 (patch)
tree352c2f01c3b989e1870be5703485231a27eecc2d
parentcf51b514c7debe6260581b237818a62f75684d67 (diff)
[Backport] Security Bug 683418
Enforce that WebUI documents cannot include web content. This CL adds a new NavigationThrottle class for enforcing security properties of navigations. The first case is checking that no web content is navigated to in iframes on WebUI pages or no navigations to web content are allowed in processes having WebUI bindings. Bug: 683418 Reviewed-on: https://chromium-review.googlesource.com/726329 Change-Id: I79c2c78454283bc485e62a7b2250f75c220cd862 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--chromium/content/browser/BUILD.gn2
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.cc4
-rw-r--r--chromium/content/browser/frame_host/webui_navigation_throttle.cc59
-rw-r--r--chromium/content/browser/frame_host/webui_navigation_throttle.h46
4 files changed, 111 insertions, 0 deletions
diff --git a/chromium/content/browser/BUILD.gn b/chromium/content/browser/BUILD.gn
index d50d76b2437..fd151674282 100644
--- a/chromium/content/browser/BUILD.gn
+++ b/chromium/content/browser/BUILD.gn
@@ -835,6 +835,8 @@ jumbo_source_set("browser") {
"frame_host/render_frame_proxy_host.h",
"frame_host/render_widget_host_view_guest.cc",
"frame_host/render_widget_host_view_guest.h",
+ "frame_host/webui_navigation_throttle.cc",
+ "frame_host/webui_navigation_throttle.h",
"generic_sensor/sensor_provider_proxy_impl.cc",
"generic_sensor/sensor_provider_proxy_impl.h",
"geolocation/geolocation_service_impl.cc",
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.cc b/chromium/content/browser/frame_host/navigation_handle_impl.cc
index 89a41274745..e772bf038fd 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.cc
@@ -22,6 +22,7 @@
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/frame_host/webui_navigation_throttle.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_navigation_handle.h"
@@ -1169,6 +1170,9 @@ void NavigationHandleImpl::RegisterNavigationThrottles() {
throttles_ = GetDelegate()->CreateThrottlesForNavigation(this);
+ // Enforce rules for WebUI navigations.
+ AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(this));
+
// Check for renderer-inititated main frame navigations to data URLs. This is
// done first as it may block the main frame navigation altogether.
AddThrottle(DataUrlNavigationThrottle::CreateThrottleForNavigation(this));
diff --git a/chromium/content/browser/frame_host/webui_navigation_throttle.cc b/chromium/content/browser/frame_host/webui_navigation_throttle.cc
new file mode 100644
index 00000000000..625b1cb19fe
--- /dev/null
+++ b/chromium/content/browser/frame_host/webui_navigation_throttle.cc
@@ -0,0 +1,59 @@
+// Copyright 2017 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.
+
+#include "content/browser/frame_host/webui_navigation_throttle.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/url_constants.h"
+
+namespace content {
+
+WebUINavigationThrottle::WebUINavigationThrottle(
+ NavigationHandle* navigation_handle)
+ : NavigationThrottle(navigation_handle) {}
+
+WebUINavigationThrottle::~WebUINavigationThrottle() {}
+
+NavigationThrottle::ThrottleCheckResult
+WebUINavigationThrottle::WillStartRequest() {
+ // Allow only chrome: scheme documents to be navigated to.
+ if (navigation_handle()->GetURL().SchemeIs(kChromeUIScheme))
+ return PROCEED;
+
+ return BLOCK_REQUEST;
+}
+
+const char* WebUINavigationThrottle::GetNameForLogging() {
+ return "WebUINavigationThrottle";
+}
+
+// static
+std::unique_ptr<NavigationThrottle>
+WebUINavigationThrottle::CreateThrottleForNavigation(
+ NavigationHandle* navigation_handle) {
+ // Create the throttle only for subframe navigations.
+ if (navigation_handle->IsInMainFrame())
+ return nullptr;
+
+ RenderFrameHostImpl* parent =
+ static_cast<NavigationHandleImpl*>(navigation_handle)
+ ->frame_tree_node()
+ ->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.
+ if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ parent->GetProcess()->GetID()) ||
+ parent->GetLastCommittedURL().SchemeIs(kChromeUIScheme)) {
+ return std::make_unique<WebUINavigationThrottle>(navigation_handle);
+ }
+
+ return nullptr;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/frame_host/webui_navigation_throttle.h b/chromium/content/browser/frame_host/webui_navigation_throttle.h
new file mode 100644
index 00000000000..b47aa830487
--- /dev/null
+++ b/chromium/content/browser/frame_host/webui_navigation_throttle.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_WEBUI_NAVIGATION_THROTTLE_H_
+#define CONTENT_BROWSER_FRAME_HOST_WEBUI_NAVIGATION_THROTTLE_H_
+
+#include "content/public/browser/navigation_throttle.h"
+
+namespace content {
+
+// This NavigationThrottle class is used to check for subframe navigations to
+// web content in WebUI processes and/or chrome:// documents. When the
+// parent frame is at a chrome:// URL or is in a process with WebUI
+// bindings, subframes are only allowed to navigate to chrome:// URLs.
+// Note: There are WebUI documents that live on non-chrome: schemes and do
+// not have WebUI bindings. Those are not covered by this restriction.
+//
+// This is an important security property to uphold, because by default
+// WebUI documents have high privileges and if malicious web content is
+// loaded in their process, it can be used as an easy step towards a sandbox
+// escape.
+//
+// Note: Navigations in the main frame are allowed, as those will result in a
+// process change with BrowsingInstance change and drop of privileges.
+// Subframes are resticted because they must be in the same BrowsingInstance
+// and would have the ability to communicate with the parent document.
+class WebUINavigationThrottle : public NavigationThrottle {
+ public:
+ static std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation(
+ NavigationHandle* navigation_handle);
+
+ explicit WebUINavigationThrottle(NavigationHandle* navigation_handle);
+ ~WebUINavigationThrottle() override;
+
+ // NavigationThrottle methods
+ ThrottleCheckResult WillStartRequest() override;
+ const char* GetNameForLogging() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WebUINavigationThrottle);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FRAME_HOST_WEBUI_NAVIGATION_THROTTLE_H_