summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@qt.io>2019-03-20 16:01:35 +0100
committerMichael BrĂ¼ning <michael.bruning@qt.io>2019-03-27 15:19:17 +0000
commitc6d0023bc59f48abec48597e30bdacf498d61f13 (patch)
tree86cdff58eb0b8d5976de2a11c52ca3d6e51190ed
parenta63d51633abf7cc7a6031a51addc9b7d48db10d9 (diff)
downloadqtwebengine-chromium-c6d0023bc59f48abec48597e30bdacf498d61f13.tar.gz
[Backport] CVE-2019-5802 (5/5)
Manual bckport of original patch by Charlie Harrison <csharrison@chromium.org>: Implement opener download metrics for cross-process opener navigations Currently, the metrics only account for the same-process flow through BeginNavigation. With this CL, we plumb the relevant information through the RemoteFrame / RenderFrameProxy / OpenURL path. Bug: 632514 Reviewed-on: https://chromium-review.googlesource.com/c/1380967 Change-Id: Ie4062172a52d9c329db6fa4a229689b3ed67b5ef Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.cc16
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.h2
-rw-r--r--chromium/content/browser/frame_host/navigator.h1
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.cc6
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.h1
-rw-r--r--chromium/content/browser/frame_host/render_frame_proxy_host.cc3
-rw-r--r--chromium/content/common/frame_messages.h1
-rw-r--r--chromium/content/renderer/render_frame_impl.cc47
-rw-r--r--chromium/content/renderer/render_frame_impl.h9
-rw-r--r--chromium/content/renderer/render_frame_proxy.cc3
-rw-r--r--chromium/content/renderer/render_frame_proxy.h1
-rw-r--r--chromium/third_party/blink/public/web/web_remote_frame_client.h1
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client.h1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/core/loader/empty_clients.h1
18 files changed, 72 insertions, 36 deletions
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.cc b/chromium/content/browser/frame_host/navigation_controller_impl.cc
index 2945ef2f662..ea4250efdc2 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.cc
@@ -2004,6 +2004,7 @@ void NavigationControllerImpl::NavigateFromFrameProxy(
const Referrer& referrer,
ui::PageTransition page_transition,
bool should_replace_current_entry,
+ NavigationDownloadPolicy download_policy,
const std::string& method,
scoped_refptr<network::ResourceRequestBody> post_body,
const std::string& extra_headers,
@@ -2104,7 +2105,7 @@ void NavigationControllerImpl::NavigateFromFrameProxy(
CreateNavigationRequestFromLoadParams(
render_frame_host->frame_tree_node(), params, override_user_agent,
should_replace_current_entry, false /* has_user_gesture */,
- ReloadType::NONE, *entry, frame_entry.get());
+ download_policy, ReloadType::NONE, *entry, frame_entry.get());
if (!request)
return;
@@ -2573,8 +2574,8 @@ void NavigationControllerImpl::NavigateWithoutEntry(
std::unique_ptr<NavigationRequest> request =
CreateNavigationRequestFromLoadParams(
node, params, override_user_agent, should_replace_current_entry,
- has_user_gesture, reload_type, *pending_entry_,
- pending_entry_->GetFrameEntry(node));
+ has_user_gesture, NavigationDownloadPolicy::kAllow, reload_type,
+ *pending_entry_, pending_entry_->GetFrameEntry(node));
// If the navigation couldn't start, return immediately and discard the
// pending NavigationEntry.
@@ -2772,9 +2773,12 @@ NavigationControllerImpl::CreateNavigationRequestFromLoadParams(
// Create the NavigationParams based on |params|.
bool is_view_source_mode = virtual_url.SchemeIs(kViewSourceScheme);
- NavigationDownloadPolicy download_policy =
- is_view_source_mode ? NavigationDownloadPolicy::kDisallowViewSource
- : NavigationDownloadPolicy::kAllow;
+ // Update |download_policy| if the virtual URL is view-source. Why do this
+ // now? Possibly the URL could be rewritten to a view-source via some URL
+ // handler.
+ if (is_view_source_mode)
+ download_policy = NavigationDownloadPolicy::kDisallowViewSource;
+
const GURL& history_url_for_data_url =
params.base_url_for_data_url.is_empty() ? GURL() : virtual_url;
CommonNavigationParams common_params(
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.h b/chromium/content/browser/frame_host/navigation_controller_impl.h
index 6e673629d65..7cc4d81c8aa 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.h
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.h
@@ -111,6 +111,7 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
const Referrer& referrer,
ui::PageTransition page_transition,
bool should_replace_current_entry,
+ NavigationDownloadPolicy download_policy,
const std::string& method,
scoped_refptr<network::ResourceRequestBody> post_body,
const std::string& extra_headers,
@@ -311,6 +312,7 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
bool override_user_agent,
bool should_replace_current_entry,
bool has_user_gesture,
+ NavigationDownloadPolicy download_policy,
ReloadType reload_type,
const NavigationEntryImpl& entry,
FrameNavigationEntry* frame_entry);
diff --git a/chromium/content/browser/frame_host/navigator.h b/chromium/content/browser/frame_host/navigator.h
index fe5fe87f06f..fd0b9dd15fb 100644
--- a/chromium/content/browser/frame_host/navigator.h
+++ b/chromium/content/browser/frame_host/navigator.h
@@ -131,6 +131,7 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
const Referrer& referrer,
ui::PageTransition page_transition,
bool should_replace_current_entry,
+ NavigationDownloadPolicy download_policy,
const std::string& method,
scoped_refptr<network::ResourceRequestBody> post_body,
const std::string& extra_headers,
diff --git a/chromium/content/browser/frame_host/navigator_impl.cc b/chromium/content/browser/frame_host/navigator_impl.cc
index c6f47ecde41..e9a8c947080 100644
--- a/chromium/content/browser/frame_host/navigator_impl.cc
+++ b/chromium/content/browser/frame_host/navigator_impl.cc
@@ -521,6 +521,7 @@ void NavigatorImpl::NavigateFromFrameProxy(
const Referrer& referrer,
ui::PageTransition page_transition,
bool should_replace_current_entry,
+ NavigationDownloadPolicy download_policy,
const std::string& method,
scoped_refptr<network::ResourceRequestBody> post_body,
const std::string& extra_headers,
@@ -571,8 +572,9 @@ void NavigatorImpl::NavigateFromFrameProxy(
controller_->NavigateFromFrameProxy(
render_frame_host, url, is_renderer_initiated, source_site_instance,
- referrer_to_use, page_transition, should_replace_current_entry, method,
- post_body, extra_headers, std::move(blob_url_loader_factory));
+ referrer_to_use, page_transition,
+ should_replace_current_entry, download_policy, method, post_body,
+ extra_headers, std::move(blob_url_loader_factory));
}
void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node,
diff --git a/chromium/content/browser/frame_host/navigator_impl.h b/chromium/content/browser/frame_host/navigator_impl.h
index b97af7081e4..c7e43d3fb5e 100644
--- a/chromium/content/browser/frame_host/navigator_impl.h
+++ b/chromium/content/browser/frame_host/navigator_impl.h
@@ -82,6 +82,7 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
const Referrer& referrer,
ui::PageTransition page_transition,
bool should_replace_current_entry,
+ NavigationDownloadPolicy download_policy,
const std::string& method,
scoped_refptr<network::ResourceRequestBody> post_body,
const std::string& extra_headers,
diff --git a/chromium/content/browser/frame_host/render_frame_proxy_host.cc b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
index b06a4b9242d..9f9cb2dd1d3 100644
--- a/chromium/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
@@ -353,7 +353,8 @@ void RenderFrameProxyHost::OnOpenURL(
// to PAGE_TRANSITION_FORM_SUBMIT. See https://crbug.com/829827.
frame_tree_node_->navigator()->NavigateFromFrameProxy(
current_rfh, validated_url, site_instance_.get(), params.referrer,
- ui::PAGE_TRANSITION_LINK, params.should_replace_current_entry,
+ ui::PAGE_TRANSITION_LINK,
+ params.should_replace_current_entry, params.download_policy,
params.uses_post ? "POST" : "GET", params.resource_request_body,
params.extra_headers, std::move(blob_url_loader_factory));
}
diff --git a/chromium/content/common/frame_messages.h b/chromium/content/common/frame_messages.h
index f36396d9feb..bfc597c92c5 100644
--- a/chromium/content/common/frame_messages.h
+++ b/chromium/content/common/frame_messages.h
@@ -570,6 +570,7 @@ IPC_STRUCT_BEGIN(FrameHostMsg_OpenURL_Params)
IPC_STRUCT_MEMBER(bool, is_history_navigation_in_new_child)
IPC_STRUCT_MEMBER(blink::WebTriggeringEventInfo, triggering_event_info)
IPC_STRUCT_MEMBER(mojo::MessagePipeHandle, blob_url_token)
+ IPC_STRUCT_MEMBER(content::NavigationDownloadPolicy, download_policy)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(FrameHostMsg_DownloadUrl_Params)
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc
index ae9a4b0a8a9..c05fba60224 100644
--- a/chromium/content/renderer/render_frame_impl.cc
+++ b/chromium/content/renderer/render_frame_impl.cc
@@ -490,26 +490,6 @@ WebURLRequest CreateURLRequestForNavigation(
return request;
}
-NavigationDownloadPolicy GetDownloadPolicy(
- bool prevent_sandboxed_download,
- bool is_opener_navigation,
- const blink::WebURLRequest& request,
- const WebSecurityOrigin& current_origin) {
- if (prevent_sandboxed_download)
- return NavigationDownloadPolicy::kDisallowSandbox;
- if (!is_opener_navigation)
- return NavigationDownloadPolicy::kAllow;
- bool gesture = request.HasUserGesture();
- bool cross_origin = !request.RequestorOrigin().CanAccess(current_origin);
- if (!gesture && cross_origin)
- return NavigationDownloadPolicy::kAllowOpenerCrossOriginNoGesture;
- if (!gesture)
- return NavigationDownloadPolicy::kAllowOpenerNoGesture;
- if (cross_origin)
- return NavigationDownloadPolicy::kAllowOpenerCrossOrigin;
- return NavigationDownloadPolicy::kAllowOpener;
-}
-
CommonNavigationParams MakeCommonNavigationParams(
const WebSecurityOrigin& current_origin,
const blink::WebLocalFrameClient::NavigationPolicyInfo& info,
@@ -551,8 +531,10 @@ CommonNavigationParams MakeCommonNavigationParams(
static_cast<RequestExtraData*>(info.url_request.GetExtraData());
DCHECK(extra_data);
NavigationDownloadPolicy download_policy =
- GetDownloadPolicy(prevent_sandboxed_download, info.is_opener_navigation,
- info.url_request, current_origin);
+ prevent_sandboxed_download
+ ? NavigationDownloadPolicy::kDisallowSandbox
+ : RenderFrameImpl::GetOpenerDownloadPolicy(
+ info.is_opener_navigation, info.url_request, current_origin);
return CommonNavigationParams(
info.url_request.Url(), referrer, extra_data->transition_type(),
navigation_type, download_policy, info.replaces_current_history_item, GURL(), GURL(),
@@ -1432,6 +1414,24 @@ blink::WebFrame* RenderFrameImpl::ResolveOpener(int opener_frame_routing_id) {
return nullptr;
}
+// static
+NavigationDownloadPolicy RenderFrameImpl::GetOpenerDownloadPolicy(
+ bool is_opener_navigation,
+ const blink::WebURLRequest& request,
+ const WebSecurityOrigin& current_origin) {
+ if (!is_opener_navigation)
+ return NavigationDownloadPolicy::kAllow;
+ bool gesture = request.HasUserGesture();
+ bool cross_origin = !request.RequestorOrigin().CanAccess(current_origin);
+ if (!gesture && cross_origin)
+ return NavigationDownloadPolicy::kAllowOpenerCrossOriginNoGesture;
+ if (!gesture)
+ return NavigationDownloadPolicy::kAllowOpenerNoGesture;
+ if (cross_origin)
+ return NavigationDownloadPolicy::kAllowOpenerCrossOrigin;
+ return NavigationDownloadPolicy::kAllowOpener;
+}
+
blink::WebURL RenderFrameImpl::OverrideFlashEmbedWithHTML(
const blink::WebURL& url) {
return GetContentClient()->renderer()->OverrideFlashEmbedWithHTML(url);
@@ -6598,6 +6598,9 @@ void RenderFrameImpl::OpenURL(const NavigationPolicyInfo& info,
if (is_history_navigation_in_new_child)
params.is_history_navigation_in_new_child = true;
+ params.download_policy = RenderFrameImpl::GetOpenerDownloadPolicy(
+ info.is_opener_navigation, info.url_request,
+ frame_->GetSecurityOrigin());
Send(new FrameHostMsg_OpenURL(routing_id_, params));
}
diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h
index 9e9ca760952..688af98b01d 100644
--- a/chromium/content/renderer/render_frame_impl.h
+++ b/chromium/content/renderer/render_frame_impl.h
@@ -275,6 +275,15 @@ class CONTENT_EXPORT RenderFrameImpl
// routing ID.
static blink::WebFrame* ResolveOpener(int opener_frame_routing_id);
+ // Gets the download policy for a given navigation with regard to its opener
+ // status. We are trying to block downloads resulting from x-origin opener
+ // navigations if they do not have a gesture. See https://crbug.com/632514 for
+ // background.
+ static NavigationDownloadPolicy GetOpenerDownloadPolicy(
+ bool is_opener_navigation,
+ const blink::WebURLRequest& request,
+ const blink::WebSecurityOrigin& current_origin);
+
// Overwrites the given URL to use an HTML5 embed if possible.
blink::WebURL OverrideFlashEmbedWithHTML(const blink::WebURL& url) override;
diff --git a/chromium/content/renderer/render_frame_proxy.cc b/chromium/content/renderer/render_frame_proxy.cc
index f3e8c457e97..ccc734e07dd 100644
--- a/chromium/content/renderer/render_frame_proxy.cc
+++ b/chromium/content/renderer/render_frame_proxy.cc
@@ -769,6 +769,7 @@ void RenderFrameProxy::ForwardPostMessage(
void RenderFrameProxy::Navigate(const blink::WebURLRequest& request,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojo::ScopedMessagePipeHandle blob_url_token) {
FrameHostMsg_OpenURL_Params params;
params.url = request.Url();
@@ -783,6 +784,8 @@ void RenderFrameProxy::Navigate(const blink::WebURLRequest& request,
params.user_gesture = request.HasUserGesture();
params.triggering_event_info = blink::WebTriggeringEventInfo::kUnknown;
params.blob_url_token = blob_url_token.release();
+ params.download_policy = RenderFrameImpl::GetOpenerDownloadPolicy(
+ is_opener_navigation, request, web_frame_->GetSecurityOrigin());
Send(new FrameHostMsg_OpenURL(routing_id_, params));
}
diff --git a/chromium/content/renderer/render_frame_proxy.h b/chromium/content/renderer/render_frame_proxy.h
index d906ad3a279..abfdabbfb27 100644
--- a/chromium/content/renderer/render_frame_proxy.h
+++ b/chromium/content/renderer/render_frame_proxy.h
@@ -192,6 +192,7 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
bool has_user_gesture) override;
void Navigate(const blink::WebURLRequest& request,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojo::ScopedMessagePipeHandle blob_url_token) override;
void FrameRectsChanged(const blink::WebRect& local_frame_rect,
const blink::WebRect& screen_space_rect) override;
diff --git a/chromium/third_party/blink/public/web/web_remote_frame_client.h b/chromium/third_party/blink/public/web/web_remote_frame_client.h
index afefb61736c..acf312efcc2 100644
--- a/chromium/third_party/blink/public/web/web_remote_frame_client.h
+++ b/chromium/third_party/blink/public/web/web_remote_frame_client.h
@@ -41,6 +41,7 @@ class WebRemoteFrameClient {
// A remote frame was asked to start a navigation.
virtual void Navigate(const WebURLRequest& request,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojo::ScopedMessagePipeHandle blob_url_token) {}
virtual void Reload(WebFrameLoadType, ClientRedirectPolicy) {}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc b/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
index 7a664c13f71..f1751b4d3ed 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -9850,6 +9850,7 @@ class RemoteNavigationClient
// FrameTestHelpers::TestWebRemoteFrameClient:
void Navigate(const WebURLRequest& request,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojo::ScopedMessagePipeHandle) override {
last_request_ = request;
}
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
index ae704ae6005..f7cdd9aa904 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -86,10 +86,12 @@ void RemoteFrame::Navigate(const FrameLoadRequest& passed_request) {
FrameLoader::SetReferrerForFrameRequest(frame_request);
FrameLoader::UpgradeInsecureRequest(frame_request.GetResourceRequest(),
frame_request.OriginDocument());
-
+ Document* document = frame_request.OriginDocument();
+ bool is_opener_navigation = document && document->GetFrame() &&
+ document->GetFrame()->Client()->Opener() == this;
Client()->Navigate(frame_request.GetResourceRequest(),
frame_request.ReplacesCurrentItem(),
- frame_request.GetBlobURLToken());
+ is_opener_navigation, frame_request.GetBlobURLToken());
}
void RemoteFrame::Reload(WebFrameLoadType frame_load_type,
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h
index f578bbfdd7d..0b2c792a4e6 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h
@@ -30,6 +30,7 @@ class RemoteFrameClient : public FrameClient {
virtual void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojom::blink::BlobURLTokenPtr) = 0;
virtual void Reload(WebFrameLoadType, ClientRedirectPolicy) = 0;
unsigned BackForwardLength() override = 0;
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
index 25d988f493e..71551e25846 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
@@ -111,11 +111,12 @@ base::UnguessableToken RemoteFrameClientImpl::GetDevToolsFrameToken() const {
void RemoteFrameClientImpl::Navigate(
const ResourceRequest& request,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojom::blink::BlobURLTokenPtr blob_url_token) {
if (web_frame_->Client()) {
- web_frame_->Client()->Navigate(WrappedResourceRequest(request),
- should_replace_current_entry,
- blob_url_token.PassInterface().PassHandle());
+ web_frame_->Client()->Navigate(
+ WrappedResourceRequest(request), should_replace_current_entry,
+ is_opener_navigation, blob_url_token.PassInterface().PassHandle());
}
}
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
index 0e9871705b3..c9c622f586d 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
@@ -35,6 +35,7 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
// RemoteFrameClient overrides:
void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojom::blink::BlobURLTokenPtr) override;
void Reload(WebFrameLoadType, ClientRedirectPolicy) override;
unsigned BackForwardLength() override;
diff --git a/chromium/third_party/blink/renderer/core/loader/empty_clients.h b/chromium/third_party/blink/renderer/core/loader/empty_clients.h
index dbb68e5e649..0387515ff18 100644
--- a/chromium/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/chromium/third_party/blink/renderer/core/loader/empty_clients.h
@@ -413,6 +413,7 @@ class CORE_EXPORT EmptyRemoteFrameClient : public RemoteFrameClient {
// RemoteFrameClient implementation.
void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
+ bool is_opener_navigation,
mojom::blink::BlobURLTokenPtr) override {}
void Reload(WebFrameLoadType, ClientRedirectPolicy) override {}
unsigned BackForwardLength() override { return 0; }