diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2019-03-18 17:51:55 +0100 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2019-03-27 15:18:28 +0000 |
commit | a34d2fb5dd1e77bea764ea2d09401b305786197a (patch) | |
tree | d27e5a3abd3e34365e058625e673291905910ba2 | |
parent | 64d3770e5e9cd7baeb15f8a907658c3980f7eb7e (diff) | |
download | qtwebengine-chromium-a34d2fb5dd1e77bea764ea2d09401b305786197a.tar.gz |
[Backport] CVE-2019-5802 (3/5)
Backport of original patch by Charlie Harrison
<csharrison@chromium.org>:
Add an API for adding browser-side UseCounters to //content
This CL:
1. Adds method to ContentBrowserClient which allows logging blink
UseCounters scoped to a given RenderFrameHost.
2. Uses this new API to log UseCounters for opener navigations resulting
in downloads.
Bug: 632514
Change-Id: I0017563fe5bb15bc3b849ec3ee17b268d99ec5c5
Reviewed-on: https://chromium-review.googlesource.com/c/1324244
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
8 files changed, 37 insertions, 7 deletions
diff --git a/chromium/content/browser/frame_host/navigation_request.cc b/chromium/content/browser/frame_host/navigation_request.cc index 57c43b97955..a7ca9fe4cda 100644 --- a/chromium/content/browser/frame_host/navigation_request.cc +++ b/chromium/content/browser/frame_host/navigation_request.cc @@ -68,6 +68,7 @@ #include "services/network/public/cpp/url_loader_completion_status.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" #include "third_party/blink/public/platform/resource_request_blocked_reason.h" +#include "third_party/blink/public/platform/web_feature.mojom.h" #include "third_party/blink/public/platform/web_mixed_content_context_type.h" #include "url/url_constants.h" @@ -895,8 +896,21 @@ void NavigationRequest::OnResponseStarted( std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, + NavigationDownloadPolicy download_policy, bool is_stream, base::Optional<SubresourceLoaderParams> subresource_loader_params) { + is_download_ = is_download && IsNavigationDownloadAllowed(download_policy); + + // Log UseCounters for opener navigations. + if (is_download && + download_policy == + NavigationDownloadPolicy::kAllowOpenerCrossOriginNoGesture) { + GetContentClient()->browser()->LogWebFeatureForCurrentPage( + frame_tree_node_->current_frame_host(), + blink::mojom::WebFeature:: + kOpenerNavigationDownloadCrossOriginNoGesture); + } + DCHECK(state_ == STARTED); DCHECK(response); TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationRequest", this, @@ -905,7 +919,7 @@ void NavigationRequest::OnResponseStarted( // Check if the response should be sent to a renderer. response_should_be_rendered_ = - !is_download && (!response->head.headers.get() || + !is_download_ && (!response->head.headers.get() || (response->head.headers->response_code() != 204 && response->head.headers->response_code() != 205)); @@ -1003,7 +1017,6 @@ void NavigationRequest::OnResponseStarted( url_loader_client_endpoints_ = std::move(url_loader_client_endpoints); ssl_info_ = response->head.ssl_info.has_value() ? *response->head.ssl_info : net::SSLInfo(); - is_download_ = is_download; subresource_loader_params_ = std::move(subresource_loader_params); @@ -1042,7 +1055,7 @@ void NavigationRequest::OnResponseStarted( // know how to display the content. We follow Firefox here and show our // own error page instead of intercepting the request as a stream or a // download. - if (is_download && (response->head.headers.get() && + if (is_download_ && (response->head.headers.get() && (response->head.headers->response_code() / 100 != 2))) { navigation_handle_->set_net_error_code(net::ERR_INVALID_RESPONSE); frame_tree_node_->ResetNavigationRequest(false, true); @@ -1070,7 +1083,7 @@ void NavigationRequest::OnResponseStarted( navigation_handle_->WillProcessResponse( render_frame_host, response->head.headers.get(), response->head.connection_info, response->head.socket_address, ssl_info_, - request_id, common_params_.should_replace_current_entry, is_download, + request_id, common_params_.should_replace_current_entry, is_download,_ is_stream, base::Bind(&NavigationRequest::OnWillProcessResponseChecksComplete, base::Unretained(this))); diff --git a/chromium/content/browser/frame_host/navigation_request.h b/chromium/content/browser/frame_host/navigation_request.h index d358e5c8840..51a636ce7f5 100644 --- a/chromium/content/browser/frame_host/navigation_request.h +++ b/chromium/content/browser/frame_host/navigation_request.h @@ -235,6 +235,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate { std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, + NavigationDownloadPolicy download_policy, bool is_stream, base::Optional<SubresourceLoaderParams> subresource_loader_params) override; diff --git a/chromium/content/browser/loader/navigation_url_loader_delegate.h b/chromium/content/browser/loader/navigation_url_loader_delegate.h index c7d238283e1..5008698b89d 100644 --- a/chromium/content/browser/loader/navigation_url_loader_delegate.h +++ b/chromium/content/browser/loader/navigation_url_loader_delegate.h @@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/optional.h" #include "content/common/content_export.h" +#include "content/common/navigation_params.h" #include "services/network/public/mojom/url_loader.mojom.h" namespace net { @@ -45,12 +46,18 @@ class CONTENT_EXPORT NavigationURLLoaderDelegate { // necessary info to create a custom subresource loader in the renderer // process if the navigated context is controlled by a request interceptor // like AppCache or ServiceWorker. + // + // |is_download| is true if the request must be downloaded, if it isn't + // disallowed. + // + // |download_policy| specifies if downloading is disallowed. virtual void OnResponseStarted( const scoped_refptr<network::ResourceResponse>& response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<NavigationData> navigation_data, const GlobalRequestID& request_id, bool is_download, + NavigationDownloadPolicy download_policy, bool is_stream, base::Optional<SubresourceLoaderParams> subresource_loader_params) = 0; diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.cc b/chromium/content/browser/loader/navigation_url_loader_impl.cc index 2abd537d978..c4cbf356752 100644 --- a/chromium/content/browser/loader/navigation_url_loader_impl.cc +++ b/chromium/content/browser/loader/navigation_url_loader_impl.cc @@ -1464,8 +1464,8 @@ void NavigationURLLoaderImpl::OnReceiveResponse( delegate_->OnResponseStarted( std::move(response), std::move(url_loader_client_endpoints), - std::move(navigation_data), global_request_id, - is_download && IsNavigationDownloadAllowed(download_policy_), is_stream, + std::move(navigation_data), global_request_id, is_download, + download_policy_, is_stream, request_controller_->TakeSubresourceLoaderParams()); } diff --git a/chromium/content/common/navigation_params.h b/chromium/content/common/navigation_params.h index c4423040180..819ac58fc97 100644 --- a/chromium/content/common/navigation_params.h +++ b/chromium/content/common/navigation_params.h @@ -89,7 +89,8 @@ enum class NavigationDownloadPolicy { // Returns whether the given |policy| should allow for a download. This function // should be removed when http://crbug.com/632514 is resolved, when callers will // just compare with kAllow. -bool IsNavigationDownloadAllowed(NavigationDownloadPolicy policy); +bool CONTENT_EXPORT +IsNavigationDownloadAllowed(NavigationDownloadPolicy policy); // Used by all navigation IPCs. struct CONTENT_EXPORT CommonNavigationParams { diff --git a/chromium/content/public/browser/content_browser_client.h b/chromium/content/public/browser/content_browser_client.h index 34d4293bf2b..bd230a28c4f 100644 --- a/chromium/content/public/browser/content_browser_client.h +++ b/chromium/content/public/browser/content_browser_client.h @@ -1284,6 +1284,12 @@ class CONTENT_EXPORT ContentBrowserClient { // default implementation provides nullptr OverlayWindow. virtual std::unique_ptr<OverlayWindow> CreateWindowForPictureInPicture( PictureInPictureWindowController* controller); + + // Browser-side API to log blink UseCounters for events that don't occur in + // the renderer. + virtual void LogWebFeatureForCurrentPage( + content::RenderFrameHost* render_frame_host, + blink::mojom::WebFeature feature) {} }; } // namespace content diff --git a/chromium/third_party/blink/public/platform/web_feature.mojom b/chromium/third_party/blink/public/platform/web_feature.mojom index 40516ff9b5f..9c77590a8c6 100644 --- a/chromium/third_party/blink/public/platform/web_feature.mojom +++ b/chromium/third_party/blink/public/platform/web_feature.mojom @@ -1974,6 +1974,7 @@ enum WebFeature { kV8RTCPeerConnection_AddTransceiver_Method = 2513, kV8RTCRtpTransceiver_Direction_AttributeGetter = 2514, kV8RTCRtpTransceiver_Direction_AttributeSetter = 2515, + kOpenerNavigationDownloadCrossOriginNoGesture = 2649, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots. diff --git a/chromium/tools/metrics/histograms/enums.xml b/chromium/tools/metrics/histograms/enums.xml index a9427402395..294f864309a 100644 --- a/chromium/tools/metrics/histograms/enums.xml +++ b/chromium/tools/metrics/histograms/enums.xml @@ -19464,6 +19464,7 @@ Called by update_net_error_codes.py.--> <int value="2513" label="V8RTCPeerConnection_AddTransceiver_Method"/> <int value="2514" label="V8RTCRtpTransceiver_Direction_AttributeGetter"/> <int value="2515" label="V8RTCRtpTransceiver_Direction_AttributeSetter"/> + <int value="2649" label="OpenerNavigationDownloadCrossOriginNoGesture"/> </enum> <enum name="FeedbackSource"> |