diff options
author | liberato@chromium.org <liberato@chromium.org> | 2019-10-10 19:30:15 +0000 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2020-01-16 13:33:52 +0000 |
commit | b7ce677ea5c389d4187454e90466b889a3fec0aa (patch) | |
tree | 91bfaf178b6b7ee1091f808639659a81e522a862 | |
parent | e89fce7cfa3ca9736edb7380b876bd4934615ea7 (diff) | |
download | qtwebengine-chromium-b7ce677ea5c389d4187454e90466b889a3fec0aa.tar.gz |
[Backport] CVE-2019-13745 2/2
Disallow cross-origin redirects for media downloads.
Cross-origin redirects for downloads aren't allowed, but media
elements didn't notice. This CL causes them to fail rather than
download or navigate.
It replaces LocalFrameClient::CrossOriginRedirects with the
pre-existing network::mojom::RedirectMode, which includes the
option kError. We use that to indicate that no cross-origin
redirect should be followed.
Last, this CL partially addresses a TODO in parallel_job_download to
fail redirects, but failing cross-origin redirects.
Bug: 990867
Change-Id: I6488759142d225067030a3b608253c2bc0d83a3e
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
29 files changed, 134 insertions, 90 deletions
diff --git a/chromium/components/download/content/internal/download_driver_impl.cc b/chromium/components/download/content/internal/download_driver_impl.cc index 6b81a071d13..6547ee07a57 100644 --- a/chromium/components/download/content/internal/download_driver_impl.cc +++ b/chromium/components/download/content/internal/download_driver_impl.cc @@ -183,7 +183,8 @@ void DownloadDriverImpl::Start( download_url_params->set_download_source( download::DownloadSource::INTERNAL_API); download_url_params->set_post_body(post_body); - download_url_params->set_follow_cross_origin_redirects(true); + download_url_params->set_cross_origin_redirects( + network::mojom::RedirectMode::kFollow); download_url_params->set_upload_progress_callback( base::BindRepeating(&DownloadDriverImpl::OnUploadProgress, weak_ptr_factory_.GetWeakPtr(), guid)); diff --git a/chromium/components/download/internal/common/download_item_impl.cc b/chromium/components/download/internal/common/download_item_impl.cc index 386660c5ee9..63e90f576b9 100644 --- a/chromium/components/download/internal/common/download_item_impl.cc +++ b/chromium/components/download/internal/common/download_item_impl.cc @@ -2447,7 +2447,9 @@ void DownloadItemImpl::ResumeInterruptedDownload( // will only be sent to the URL returned by GetURL(). download_params->set_referrer(GetReferrerUrl()); download_params->set_referrer_policy(net::URLRequest::NEVER_CLEAR_REFERRER); - download_params->set_follow_cross_origin_redirects(false); + download_params->set_cross_origin_redirects( + network::mojom::RedirectMode::kError); + // If the interruption was caused by content length mismatch, ignore it during // resumption. diff --git a/chromium/components/download/internal/common/download_response_handler.cc b/chromium/components/download/internal/common/download_response_handler.cc index 72ae65a8ad4..25b2b9770b8 100644 --- a/chromium/components/download/internal/common/download_response_handler.cc +++ b/chromium/components/download/internal/common/download_response_handler.cc @@ -54,7 +54,7 @@ DownloadResponseHandler::DownloadResponseHandler( bool is_parallel_request, bool is_transient, bool fetch_error_body, - bool follow_cross_origin_redirects, + network::mojom::RedirectMode cross_origin_redirects, const DownloadUrlParameters::RequestHeadersType& request_headers, const std::string& request_origin, DownloadSource download_source, @@ -70,7 +70,7 @@ DownloadResponseHandler::DownloadResponseHandler( referrer_policy_(resource_request->referrer_policy), is_transient_(is_transient), fetch_error_body_(fetch_error_body), - follow_cross_origin_redirects_(follow_cross_origin_redirects), + cross_origin_redirects_(cross_origin_redirects), first_origin_(url::Origin::Create(resource_request->url)), request_headers_(request_headers), request_origin_(request_origin), @@ -174,16 +174,26 @@ void DownloadResponseHandler::OnReceiveRedirect( return; } - if (!follow_cross_origin_redirects_ && - !first_origin_.IsSameOriginWith( + if (!first_origin_.IsSameOriginWith( url::Origin::Create(redirect_info.new_url))) { - abort_reason_ = DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT; - url_chain_.push_back(redirect_info.new_url); - method_ = redirect_info.new_method; - referrer_ = GURL(redirect_info.new_referrer); - referrer_policy_ = redirect_info.new_referrer_policy; - OnComplete(network::URLLoaderCompletionStatus(net::OK)); - return; + // Cross-origin redirect. + switch (cross_origin_redirects_) { + case network::mojom::RedirectMode::kFollow: + // Pretend we didn't notice, and keep going. + break; + case network::mojom::RedirectMode::kManual: + abort_reason_ = DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT; + url_chain_.push_back(redirect_info.new_url); + method_ = redirect_info.new_method; + referrer_ = GURL(redirect_info.new_referrer); + referrer_policy_ = redirect_info.new_referrer_policy; + OnComplete(network::URLLoaderCompletionStatus(net::OK)); + return; + case network::mojom::RedirectMode::kError: + abort_reason_ = DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST; + OnComplete(network::URLLoaderCompletionStatus(net::OK)); + return; + } } if (is_partial_request_) { // A redirect while attempting a partial resumption indicates a potential diff --git a/chromium/components/download/internal/common/parallel_download_job.cc b/chromium/components/download/internal/common/parallel_download_job.cc index 45600c7054f..0bdda64336e 100644 --- a/chromium/components/download/internal/common/parallel_download_job.cc +++ b/chromium/components/download/internal/common/parallel_download_job.cc @@ -294,8 +294,10 @@ void ParallelDownloadJob::CreateRequest(int64_t offset, int64_t length) { download_params->set_referrer_policy(net::URLRequest::NEVER_CLEAR_REFERRER); // TODO(xingliu): We should not support redirect at all for parallel requests. - // Currently the network service code path still can redirect. - download_params->set_follow_cross_origin_redirects(false); + // Currently the network service code path still can redirect as long as it's + // the same origin. + download_params->set_cross_origin_redirects( + network::mojom::RedirectMode::kError); // Send the request. worker->SendRequest(std::move(download_params), url_loader_factory_getter_, diff --git a/chromium/components/download/internal/common/resource_downloader.cc b/chromium/components/download/internal/common/resource_downloader.cc index 15de44ecd42..183284be07a 100644 --- a/chromium/components/download/internal/common/resource_downloader.cc +++ b/chromium/components/download/internal/common/resource_downloader.cc @@ -162,7 +162,7 @@ void ResourceDownloader::Start( download_url_parameters->GetSaveInfo()), is_parallel_request, download_url_parameters->is_transient(), download_url_parameters->fetch_error_body(), - download_url_parameters->follow_cross_origin_redirects(), + download_url_parameters->cross_origin_redirects(), download_url_parameters->request_headers(), download_url_parameters->request_origin(), download_url_parameters->download_source(), @@ -203,7 +203,7 @@ void ResourceDownloader::InterceptResponse( false, /* is_parallel_request */ false, /* is_transient */ false, /* fetch_error_body */ - true, /* follow_cross_origin_redirects */ + network::mojom::RedirectMode::kFollow, download::DownloadUrlParameters::RequestHeadersType(), std::string(), /* request_origin */ download::DownloadSource::NAVIGATION, diff --git a/chromium/components/download/public/common/download_response_handler.h b/chromium/components/download/public/common/download_response_handler.h index 9b67e71af4b..6b1e434b21d 100644 --- a/chromium/components/download/public/common/download_response_handler.h +++ b/chromium/components/download/public/common/download_response_handler.h @@ -48,7 +48,7 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadResponseHandler bool is_parallel_request, bool is_transient, bool fetch_error_body, - bool follow_cross_origin_redirects, + network::mojom::RedirectMode cross_origin_redirects, const DownloadUrlParameters::RequestHeadersType& request_headers, const std::string& request_origin, DownloadSource download_source, @@ -91,7 +91,7 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadResponseHandler net::URLRequest::ReferrerPolicy referrer_policy_; bool is_transient_; bool fetch_error_body_; - bool follow_cross_origin_redirects_; + network::mojom::RedirectMode cross_origin_redirects_; url::Origin first_origin_; DownloadUrlParameters::RequestHeadersType request_headers_; std::string request_origin_; diff --git a/chromium/components/download/public/common/download_url_parameters.cc b/chromium/components/download/public/common/download_url_parameters.cc index 0c85c8f6a9a..5940b07cc41 100644 --- a/chromium/components/download/public/common/download_url_parameters.cc +++ b/chromium/components/download/public/common/download_url_parameters.cc @@ -35,7 +35,7 @@ DownloadUrlParameters::DownloadUrlParameters( frame_tree_node_id_(-1), url_(url), do_not_prompt_for_login_(false), - follow_cross_origin_redirects_(true), + cross_origin_redirects_(network::mojom::RedirectMode::kFollow), fetch_error_body_(false), transient_(false), traffic_annotation_(traffic_annotation), diff --git a/chromium/components/download/public/common/download_url_parameters.h b/chromium/components/download/public/common/download_url_parameters.h index ecbc0aff525..2460b37210a 100644 --- a/chromium/components/download/public/common/download_url_parameters.h +++ b/chromium/components/download/public/common/download_url_parameters.h @@ -21,6 +21,7 @@ #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request.h" #include "services/network/public/cpp/resource_request_body.h" +#include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "storage/browser/blob/blob_data_handle.h" #include "url/gurl.h" #include "url/origin.h" @@ -210,11 +211,13 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters { do_not_prompt_for_login_ = do_not_prompt; } - // If |follow_cross_origin_redirects| is true, we will follow cross origin - // redirects while downloading, otherwise, we'll attempt to navigate to the - // URL or cancel the download. - void set_follow_cross_origin_redirects(bool follow_cross_origin_redirects) { - follow_cross_origin_redirects_ = follow_cross_origin_redirects; + // If |cross_origin_redirects| is kFollow, we will follow cross origin + // redirects while downloading. If it is kManual, then we'll attempt to + // navigate to the URL or cancel the download. If it is kError, then we will + // fail the download (kFail). + void set_cross_origin_redirects( + network::mojom::RedirectMode cross_origin_redirects) { + cross_origin_redirects_ = cross_origin_redirects; } // Sets whether to download the response body even if the server returns @@ -308,8 +311,8 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters { bool prompt() const { return save_info_.prompt_for_save_location; } const GURL& url() const { return url_; } bool do_not_prompt_for_login() const { return do_not_prompt_for_login_; } - bool follow_cross_origin_redirects() const { - return follow_cross_origin_redirects_; + network::mojom::RedirectMode cross_origin_redirects() const { + return cross_origin_redirects_; } bool fetch_error_body() const { return fetch_error_body_; } bool is_transient() const { return transient_; } @@ -356,7 +359,7 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters { DownloadSaveInfo save_info_; GURL url_; bool do_not_prompt_for_login_; - bool follow_cross_origin_redirects_; + network::mojom::RedirectMode cross_origin_redirects_; bool fetch_error_body_; bool transient_; std::string guid_; diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc index 50ca50ae5c6..8c9b4538028 100644 --- a/chromium/content/browser/download/download_browsertest.cc +++ b/chromium/content/browser/download/download_browsertest.cc @@ -1832,17 +1832,54 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectDownload) { std::unique_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); auto download_parameters = std::make_unique<download::DownloadUrlParameters>( first_url, TRAFFIC_ANNOTATION_FOR_TESTS); - download_parameters->set_follow_cross_origin_redirects(true); + download_parameters->set_cross_origin_redirects( + network::mojom::RedirectMode::kFollow); DownloadManagerForShell(shell())->DownloadUrl(std::move(download_parameters)); observer->WaitForFinished(); - // Verify download is done. + // Verify download failed. std::vector<download::DownloadItem*> downloads; DownloadManagerForShell(shell())->GetAllDownloads(&downloads); EXPECT_EQ(1u, downloads.size()); EXPECT_EQ(download::DownloadItem::COMPLETE, downloads[0]->GetState()); } +// Verify that DownloadUrl can detect and fail a cross-origin URL redirect. +IN_PROC_BROWSER_TEST_F(DownloadContentTest, FailCrossOriginDownload) { + // Setup a cross-origin redirect chain with two URLs. + net::EmbeddedTestServer origin_one; + net::EmbeddedTestServer origin_two; + ASSERT_TRUE(origin_one.InitializeAndListen()); + ASSERT_TRUE(origin_two.InitializeAndListen()); + + GURL first_url = origin_one.GetURL("/first-url"); + GURL second_url = origin_two.GetURL("/download"); + + origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); + origin_one.RegisterRequestHandler( + CreateRedirectHandler("/first-url", second_url)); + origin_one.StartAcceptingConnections(); + origin_two.StartAcceptingConnections(); + + // Start a download and explicitly specify to fail cross-origin redirect. + std::unique_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); + auto download_parameters = std::make_unique<download::DownloadUrlParameters>( + first_url, TRAFFIC_ANNOTATION_FOR_TESTS); + download_parameters->set_cross_origin_redirects( + network::mojom::RedirectMode::kError); + DownloadManagerForShell(shell())->DownloadUrl(std::move(download_parameters)); + observer->WaitForFinished(); + + // Verify download is done. + std::vector<download::DownloadItem*> downloads; + DownloadManagerForShell(shell())->GetAllDownloads(&downloads); + EXPECT_EQ(1u, downloads.size()); + EXPECT_EQ(download::DownloadItem::INTERRUPTED, downloads[0]->GetState()); + + ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete()); + ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete()); +} + // Verify that DownloadUrl() to URL with unsafe scheme should fail. IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectUnsafeDownload) { // Setup a redirect chain with two URL. @@ -1864,7 +1901,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RedirectUnsafeDownload) { DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); auto download_parameters = std::make_unique<download::DownloadUrlParameters>( first_url, TRAFFIC_ANNOTATION_FOR_TESTS); - download_parameters->set_follow_cross_origin_redirects(true); + download_parameters->set_cross_origin_redirects( + network::mojom::RedirectMode::kFollow); download_manager->DownloadUrl(std::move(download_parameters)); observer->WaitForFinished(); diff --git a/chromium/content/browser/download/download_manager_impl.cc b/chromium/content/browser/download/download_manager_impl.cc index 65824478682..5a72da2d6a5 100644 --- a/chromium/content/browser/download/download_manager_impl.cc +++ b/chromium/content/browser/download/download_manager_impl.cc @@ -899,7 +899,7 @@ download::DownloadInterruptReason DownloadManagerImpl::BeginDownloadRequest( std::unique_ptr<ResourceHandler> handler( DownloadResourceHandler::CreateForNewRequest( url_request.get(), params->request_origin(), - params->download_source(), params->follow_cross_origin_redirects())); + params->download_source(), params->cross_origin_redirects())); ResourceDispatcherHostImpl::Get()->BeginURLRequest( std::move(url_request), std::move(handler), true, // download diff --git a/chromium/content/browser/download/download_resource_handler.cc b/chromium/content/browser/download/download_resource_handler.cc index fc9a9286603..d4582dab97b 100644 --- a/chromium/content/browser/download/download_resource_handler.cc +++ b/chromium/content/browser/download/download_resource_handler.cc @@ -148,10 +148,10 @@ DownloadResourceHandler::DownloadResourceHandler( net::URLRequest* request, const std::string& request_origin, download::DownloadSource download_source, - bool follow_cross_origin_redirects) + network::mojom::RedirectMode cross_origin_redirects) : ResourceHandler(request), tab_info_(new DownloadTabInfo()), - follow_cross_origin_redirects_(follow_cross_origin_redirects), + cross_origin_redirects_(cross_origin_redirects), first_origin_(url::Origin::Create(request->url())), core_(request, this, false, request_origin, download_source) { // Do UI thread initialization for tab_info_ asap after @@ -182,7 +182,7 @@ std::unique_ptr<ResourceHandler> DownloadResourceHandler::Create( net::URLRequest* request) { DCHECK_CURRENTLY_ON(BrowserThread::IO); std::unique_ptr<ResourceHandler> handler(new DownloadResourceHandler( - request, std::string(), download::DownloadSource::NAVIGATION, true)); + request, std::string(), download::DownloadSource::NAVIGATION, network::mojom::RedirectMode::kFollow)); return handler; } @@ -191,10 +191,10 @@ std::unique_ptr<ResourceHandler> DownloadResourceHandler::CreateForNewRequest( net::URLRequest* request, const std::string& request_origin, download::DownloadSource download_source, - bool follow_cross_origin_redirects) { + network::mojom::RedirectMode cross_origin_redirects) { DCHECK_CURRENTLY_ON(BrowserThread::IO); std::unique_ptr<ResourceHandler> handler(new DownloadResourceHandler( - request, request_origin, download_source, follow_cross_origin_redirects)); + request, request_origin, download_source, cross_origin_redirects)); return handler; } @@ -203,7 +203,7 @@ void DownloadResourceHandler::OnRequestRedirected( network::ResourceResponse* response, std::unique_ptr<ResourceController> controller) { url::Origin new_origin(url::Origin::Create(redirect_info.new_url)); - if (!follow_cross_origin_redirects_ && + if (network::mojom::RedirectMode::kFollow!=cross_origin_redirects_ && !first_origin_.IsSameOriginWith(new_origin)) { if (redirect_info.new_url.SchemeIsHTTPOrHTTPS() || GetContentClient()->browser()->IsHandledURL(redirect_info.new_url)) { diff --git a/chromium/content/browser/download/download_resource_handler.h b/chromium/content/browser/download/download_resource_handler.h index 2d206330813..c0088d27c6c 100644 --- a/chromium/content/browser/download/download_resource_handler.h +++ b/chromium/content/browser/download/download_resource_handler.h @@ -45,7 +45,7 @@ class CONTENT_EXPORT DownloadResourceHandler DownloadResourceHandler(net::URLRequest* request, const std::string& request_origin, download::DownloadSource download_source, - bool follow_cross_origin_redirects); + network::mojom::RedirectMode cross_origin_redirects); // static // This function is passed into ResourceDispatcherHostImpl during its @@ -63,7 +63,7 @@ class CONTENT_EXPORT DownloadResourceHandler net::URLRequest* request, const std::string& request_origin, download::DownloadSource download_source, - bool follow_cross_origin_redirects); + network::mojom::RedirectMode cross_origin_redirects); void OnRequestRedirected( const net::RedirectInfo& redirect_info, @@ -119,7 +119,7 @@ class CONTENT_EXPORT DownloadResourceHandler // deletion must occur on the IO thread. std::unique_ptr<DownloadTabInfo> tab_info_; - bool follow_cross_origin_redirects_; + network::mojom::RedirectMode cross_origin_redirects_; url::Origin first_origin_; DownloadRequestCore core_; diff --git a/chromium/content/browser/download/url_downloader.cc b/chromium/content/browser/download/url_downloader.cc index 0033149fd18..d5f45ce90d3 100644 --- a/chromium/content/browser/download/url_downloader.cc +++ b/chromium/content/browser/download/url_downloader.cc @@ -54,7 +54,7 @@ std::unique_ptr<UrlDownloader> UrlDownloader::BeginDownload( // |started_callback|. auto downloader = std::make_unique<UrlDownloader>( std::move(request), delegate, is_parallel_request, - params->request_origin(), params->follow_cross_origin_redirects(), + params->request_origin(), params->cross_origin_redirects(), params->download_source(), params->upload_callback()); downloader->Start(); @@ -66,7 +66,7 @@ UrlDownloader::UrlDownloader( base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate, bool is_parallel_request, const std::string& request_origin, - bool follow_cross_origin_redirects, + network::mojom::RedirectMode cross_origin_redirects, download::DownloadSource download_source, const download::DownloadUrlParameters::UploadProgressCallback& upload_callback) @@ -77,7 +77,7 @@ UrlDownloader::UrlDownloader( is_parallel_request, request_origin, download_source), - follow_cross_origin_redirects_(follow_cross_origin_redirects), + cross_origin_redirects_(cross_origin_redirects), upload_callback_(upload_callback) {} UrlDownloader::~UrlDownloader() = default; @@ -108,7 +108,7 @@ void UrlDownloader::OnReceivedRedirect(net::URLRequest* request, bool* defer_redirect) { DVLOG(1) << __func__ << " , request url: " << request_->url().spec() << " ,redirect url:" << redirect_info.new_url; - if (follow_cross_origin_redirects_) { + if (cross_origin_redirects_ == network::mojom::RedirectMode::kFollow) { if (!DownloadRequestUtils::IsURLSafe(ChildProcessHost::kInvalidUniqueID, redirect_info.new_url)) { core_.OnWillAbort( diff --git a/chromium/content/browser/download/url_downloader.h b/chromium/content/browser/download/url_downloader.h index 8109783bcb0..fbee4098be3 100644 --- a/chromium/content/browser/download/url_downloader.h +++ b/chromium/content/browser/download/url_downloader.h @@ -40,7 +40,7 @@ class UrlDownloader : public net::URLRequest::Delegate, base::WeakPtr<UrlDownloadHandler::Delegate> delegate, bool is_parallel_request, const std::string& request_origin, - bool follow_cross_origin_redirects, + network::mojom::RedirectMode cross_origin_redirects, download::DownloadSource download_source, const download::DownloadUrlParameters::UploadProgressCallback& upload_callback); @@ -92,7 +92,7 @@ class UrlDownloader : public net::URLRequest::Delegate, base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate_; DownloadRequestCore core_; - const bool follow_cross_origin_redirects_; + network::mojom::RedirectMode cross_origin_redirects_; download::DownloadUrlParameters::UploadProgressCallback upload_callback_; std::unique_ptr<network::UploadProgressTracker> upload_progress_tracker_; diff --git a/chromium/content/browser/frame_host/render_frame_message_filter.cc b/chromium/content/browser/frame_host/render_frame_message_filter.cc index 5815fdfd625..f65a8c48e92 100644 --- a/chromium/content/browser/frame_host/render_frame_message_filter.cc +++ b/chromium/content/browser/frame_host/render_frame_message_filter.cc @@ -334,7 +334,7 @@ void RenderFrameMessageFilter::DownloadUrl( const url::Origin& initiator, const base::string16& suggested_name, const bool use_prompt, - const bool follow_cross_origin_redirects, + network::mojom::RedirectMode cross_origin_redirects, blink::mojom::BlobURLTokenPtrInfo blob_url_token) const { if (!resource_context_) return; @@ -371,7 +371,7 @@ void RenderFrameMessageFilter::DownloadUrl( parameters->set_content_initiated(true); parameters->set_suggested_name(suggested_name); parameters->set_prompt(use_prompt); - parameters->set_follow_cross_origin_redirects(follow_cross_origin_redirects); + parameters->set_cross_origin_redirects(cross_origin_redirects); parameters->set_referrer(referrer.url); parameters->set_referrer_policy( Referrer::ReferrerPolicyForUrlRequest(referrer.policy)); @@ -460,7 +460,7 @@ void RenderFrameMessageFilter::OnDownloadUrl( DownloadUrl(params.render_view_id, params.render_frame_id, params.url, params.referrer, params.initiator_origin, params.suggested_name, - false, params.follow_cross_origin_redirects, + false, params.cross_origin_redirects, std::move(blob_url_token)); } @@ -477,7 +477,7 @@ void RenderFrameMessageFilter::OnSaveImageFromDataURL( return; DownloadUrl(render_view_id, render_frame_id, data_url, Referrer(), - url::Origin(), base::string16(), true, true, nullptr); + url::Origin(), base::string16(), true, network::mojom::RedirectMode::kFollow, nullptr); } void RenderFrameMessageFilter::OnAre3DAPIsBlocked(int render_frame_id, diff --git a/chromium/content/browser/frame_host/render_frame_message_filter.h b/chromium/content/browser/frame_host/render_frame_message_filter.h index e7900ef22a0..fc90128d916 100644 --- a/chromium/content/browser/frame_host/render_frame_message_filter.h +++ b/chromium/content/browser/frame_host/render_frame_message_filter.h @@ -79,7 +79,7 @@ class CONTENT_EXPORT RenderFrameMessageFilter : public BrowserMessageFilter { const url::Origin& initiator, const base::string16& suggested_name, const bool use_prompt, - const bool follow_cross_origin_redirects, + network::mojom::RedirectMode cross_origin_redirects, blink::mojom::BlobURLTokenPtrInfo blob_url_token) const; private: diff --git a/chromium/content/common/frame_messages.h b/chromium/content/common/frame_messages.h index 98c50231153..85ba962a917 100644 --- a/chromium/content/common/frame_messages.h +++ b/chromium/content/common/frame_messages.h @@ -594,7 +594,7 @@ IPC_STRUCT_BEGIN(FrameHostMsg_DownloadUrl_Params) IPC_STRUCT_MEMBER(content::Referrer, referrer) IPC_STRUCT_MEMBER(url::Origin, initiator_origin) IPC_STRUCT_MEMBER(base::string16, suggested_name) - IPC_STRUCT_MEMBER(bool, follow_cross_origin_redirects) + IPC_STRUCT_MEMBER(network::mojom::RedirectMode, cross_origin_redirects) IPC_STRUCT_MEMBER(mojo::MessagePipeHandle, blob_url_token) IPC_STRUCT_END() diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc index 380353d03f4..4bf01343419 100644 --- a/chromium/content/renderer/render_frame_impl.cc +++ b/chromium/content/renderer/render_frame_impl.cc @@ -4662,7 +4662,7 @@ void RenderFrameImpl::DidAddMessageToConsole( void RenderFrameImpl::DownloadURL( const blink::WebURLRequest& request, - CrossOriginRedirects cross_origin_redirect_behavior, + network::mojom::RedirectMode cross_origin_redirect_behavior, mojo::ScopedMessagePipeHandle blob_url_token) { if (ShouldThrottleDownload()) return; @@ -4675,8 +4675,7 @@ void RenderFrameImpl::DownloadURL( params.initiator_origin = request.RequestorOrigin(); if (request.GetSuggestedFilename().has_value()) params.suggested_name = request.GetSuggestedFilename()->Utf16(); - params.follow_cross_origin_redirects = - (cross_origin_redirect_behavior == CrossOriginRedirects::kFollow); + params.cross_origin_redirects = cross_origin_redirect_behavior; params.blob_url_token = blob_url_token.release(); Send(new FrameHostMsg_DownloadUrl(params)); @@ -6633,8 +6632,7 @@ void RenderFrameImpl::BeginNavigation( if (info->navigation_policy == blink::kWebNavigationPolicyDownload) { blink::mojom::BlobURLTokenPtrInfo blob_url_token = CloneBlobURLToken(info->blob_url_token.get()); - DownloadURL(info->url_request, - blink::WebLocalFrameClient::CrossOriginRedirects::kFollow, + DownloadURL(info->url_request, network::mojom::RedirectMode::kFollow, blob_url_token.PassHandle()); } else { OpenURL(std::move(info)); diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h index 67275cb1f82..fa4af4ea701 100644 --- a/chromium/content/renderer/render_frame_impl.h +++ b/chromium/content/renderer/render_frame_impl.h @@ -744,7 +744,7 @@ class CONTENT_EXPORT RenderFrameImpl unsigned source_line, const blink::WebString& stack_trace) override; void DownloadURL(const blink::WebURLRequest& request, - CrossOriginRedirects cross_origin_redirect_behavior, + network::mojom::RedirectMode cross_origin_redirect_behavior, mojo::ScopedMessagePipeHandle blob_url_token) override; void LoadErrorPage(int reason) override; void BeginNavigation(std::unique_ptr<blink::WebNavigationInfo> info) override; diff --git a/chromium/content/renderer/render_frame_impl_browsertest.cc b/chromium/content/renderer/render_frame_impl_browsertest.cc index fbcc61b3c8c..2fabc334805 100644 --- a/chromium/content/renderer/render_frame_impl_browsertest.cc +++ b/chromium/content/renderer/render_frame_impl_browsertest.cc @@ -410,9 +410,8 @@ TEST_F(RenderFrameImplTest, DownloadUrlLimit) { blink::WebSecurityOrigin::Create(GURL("http://test"))); for (int i = 0; i < 10; ++i) { - frame()->DownloadURL( - request, blink::WebLocalFrameClient::CrossOriginRedirects::kNavigate, - mojo::ScopedMessagePipeHandle()); + frame()->DownloadURL(request, network::mojom::RedirectMode::kManual, + mojo::ScopedMessagePipeHandle()); base::RunLoop().RunUntilIdle(); const IPC::Message* msg2 = render_thread_->sink().GetFirstMessageMatching( FrameHostMsg_DownloadUrl::ID); @@ -421,9 +420,8 @@ TEST_F(RenderFrameImplTest, DownloadUrlLimit) { render_thread_->sink().ClearMessages(); } - frame()->DownloadURL( - request, blink::WebLocalFrameClient::CrossOriginRedirects::kNavigate, - mojo::ScopedMessagePipeHandle()); + frame()->DownloadURL(request, network::mojom::RedirectMode::kManual, + mojo::ScopedMessagePipeHandle()); base::RunLoop().RunUntilIdle(); const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching( FrameHostMsg_DownloadUrl::ID); diff --git a/chromium/third_party/blink/public/web/DEPS b/chromium/third_party/blink/public/web/DEPS index 11b1b111f04..4c8a8f9a0d5 100644 --- a/chromium/third_party/blink/public/web/DEPS +++ b/chromium/third_party/blink/public/web/DEPS @@ -22,6 +22,7 @@ include_rules = [ "+services/metrics/public/cpp/ukm_source_id.h", "+services/network/public/mojom/cors.mojom-shared.h", "+services/network/public/mojom/cors_origin_pattern.mojom-shared.h", + "+services/network/public/mojom/fetch_api.mojom-shared.h", "+services/network/public/mojom/referrer_policy.mojom-shared.h", "+services/service_manager/public", "+ui/events/types", diff --git a/chromium/third_party/blink/public/web/web_local_frame.h b/chromium/third_party/blink/public/web/web_local_frame.h index 880911ecfc4..aaaf059c023 100644 --- a/chromium/third_party/blink/public/web/web_local_frame.h +++ b/chromium/third_party/blink/public/web/web_local_frame.h @@ -9,7 +9,7 @@ #include <set> #include "base/callback.h" -#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" +#include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" #include "third_party/blink/public/common/messaging/transferable_message.h" diff --git a/chromium/third_party/blink/public/web/web_local_frame_client.h b/chromium/third_party/blink/public/web/web_local_frame_client.h index 30fb02cee07..f257f58dddf 100644 --- a/chromium/third_party/blink/public/web/web_local_frame_client.h +++ b/chromium/third_party/blink/public/web/web_local_frame_client.h @@ -34,6 +34,7 @@ #include <memory> #include "base/unguessable_token.h" +#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" #include "third_party/blink/public/common/feature_policy/feature_policy.h" #include "third_party/blink/public/common/frame/blocked_navigation_types.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" @@ -342,10 +343,10 @@ class BLINK_EXPORT WebLocalFrameClient { // The client should handle the request as a download. // If the request is for a blob: URL, a BlobURLTokenPtr should be provided // as |blob_url_token| to ensure the correct blob gets downloaded. - enum class CrossOriginRedirects { kFollow, kNavigate }; - virtual void DownloadURL(const WebURLRequest&, - CrossOriginRedirects cross_origin_redirect_behavior, - mojo::ScopedMessagePipeHandle blob_url_token) {} + virtual void DownloadURL( + const WebURLRequest&, + network::mojom::RedirectMode cross_origin_redirect_behavior, + mojo::ScopedMessagePipeHandle blob_url_token) {} // The client should load an error page in the current frame. virtual void LoadErrorPage(int reason) {} diff --git a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 95cd13bd1c5..ddcaf609b47 100644 --- a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc @@ -640,7 +640,7 @@ void LocalFrameClientImpl::ForwardResourceTimingToParent( void LocalFrameClientImpl::DownloadURL( const ResourceRequest& request, - DownloadCrossOriginRedirects cross_origin_redirect_behavior) { + network::mojom::RedirectMode cross_origin_redirect_behavior) { if (!web_frame_->Client()) return; DCHECK(web_frame_->GetFrame()->GetDocument()); @@ -649,11 +649,9 @@ void LocalFrameClientImpl::DownloadURL( web_frame_->GetFrame()->GetDocument()->GetPublicURLManager().Resolve( request.Url(), MakeRequest(&blob_url_token)); } - web_frame_->Client()->DownloadURL( - WrappedResourceRequest(request), - static_cast<WebLocalFrameClient::CrossOriginRedirects>( - cross_origin_redirect_behavior), - blob_url_token.PassInterface().PassHandle()); + web_frame_->Client()->DownloadURL(WrappedResourceRequest(request), + cross_origin_redirect_behavior, + blob_url_token.PassInterface().PassHandle()); } void LocalFrameClientImpl::LoadErrorPage(int reason) { @@ -1265,9 +1263,4 @@ WebLocalFrameClient::AppCacheType LocalFrameClientImpl::GetAppCacheType() { return web_frame_->Client()->GetAppCacheType(); } -STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kFollow, - WebLocalFrameClient::CrossOriginRedirects::kFollow); -STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kNavigate, - WebLocalFrameClient::CrossOriginRedirects::kNavigate); - } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h index 991a32bfe9a..d91cfe30d81 100644 --- a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h @@ -132,7 +132,7 @@ class LocalFrameClientImpl final : public LocalFrameClient { void ProgressEstimateChanged(double progress_estimate) override; void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override; void DownloadURL(const ResourceRequest&, - DownloadCrossOriginRedirects) override; + network::mojom::RedirectMode) override; void LoadErrorPage(int reason) override; bool NavigateBackForward(int offset) const override; void DidAccessInitialDocument() override; diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_client.h b/chromium/third_party/blink/renderer/core/frame/local_frame_client.h index f3845a63461..6a14a1247fb 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame_client.h @@ -118,10 +118,6 @@ class WebSpellCheckPanelHostClient; struct WebScrollIntoViewParams; class WebTextCheckClient; -// Whether to follow cross origin redirects when downloading, or treating -// the download as a navigation instead. -enum class DownloadCrossOriginRedirects { kFollow, kNavigate }; - class CORE_EXPORT LocalFrameClient : public FrameClient { public: ~LocalFrameClient() override = default; @@ -188,7 +184,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient { virtual void ForwardResourceTimingToParent(const WebResourceTimingInfo&) = 0; virtual void DownloadURL(const ResourceRequest&, - DownloadCrossOriginRedirects) = 0; + network::mojom::RedirectMode) = 0; + virtual void LoadErrorPage(int reason) = 0; virtual bool NavigateBackForward(int offset) const = 0; diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc index b609ff94f66..d89218abf7a 100644 --- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc @@ -438,7 +438,7 @@ void HTMLAnchorElement::HandleClick(Event& event) { request.SetRequestContext(mojom::RequestContextType::DOWNLOAD); request.SetRequestorOrigin(GetDocument().GetSecurityOrigin()); frame->Client()->DownloadURL(request, - DownloadCrossOriginRedirects::kNavigate); + network::mojom::RedirectMode::kManual); return; } 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 469d071483f..648ec52549a 100644 --- a/chromium/third_party/blink/renderer/core/loader/empty_clients.h +++ b/chromium/third_party/blink/renderer/core/loader/empty_clients.h @@ -307,7 +307,7 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient { void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override {} void DownloadURL(const ResourceRequest&, - DownloadCrossOriginRedirects) override {} + network::mojom::RedirectMode) override {} void LoadErrorPage(int reason) override {} DocumentLoader* CreateDocumentLoader( diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc index 2e810d88f5e..08a9c39c25d 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc @@ -79,7 +79,7 @@ void MediaControlDownloadButtonElement::DefaultEventHandler(Event& event) { request.SetRequestContext(mojom::RequestContextType::DOWNLOAD); request.SetRequestorOrigin(SecurityOrigin::Create(GetDocument().Url())); GetDocument().GetFrame()->Client()->DownloadURL( - request, DownloadCrossOriginRedirects::kFollow); + request, network::mojom::RedirectMode::kError); } MediaControlInputElement::DefaultEventHandler(event); } |