Populate initiator origin in DragDownloadFileUI::InitiateDownload
.
This CL propagates the initiator origin via `content::DragDownloadFile::DragDownloadFileUI::InitiateDownload` into `download::DownloadUrlParameters::set_initiator`. Note that the initiator origin comes from trustworthy, browser-side data: - `RenderFrameHostImpl::StartDragging` passes `GetLastCommittedOrigin()` into `RenderViewHostDelegateView::StartDragging` - `WebContentsViewAura::StartDragging` stores the origin into into `ui::OSExchangeDataProviderFactory` using a call to `ui::OSExchangeDataProviderFactory::MarkRendererTaintedFromOrigin`. On Windows this CL takes the origin from `OSExchangeDataProviderFactory` and passes it directly into `DragDownloadFile`'s constructor. - `WebContentsViewMac::StartDragging` ends up storing the origin in `WebDragSource` from `web_drag_source_mac.mm`. On Mac this CL takes this origin and also passes it (indirectly, via mojo) into `DragDownloadFile`'s constructor. @lukasza has manually tested this CL on Windows using the repro steps from https://crbug.com/40060358 (@dcheng has kindly tried the repro steps on Mac). Note that `DragDownloadFile` is used on Windows and Mac, but not on Linux (i.e. the repro wouldn't have worked on Linux). Fixed: 40060358 Change-Id: I24b180473e140cbb8a56640444f2f4a306aa42fc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5692867 Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Avi Drissman <avi@chromium.org> Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org> Cr-Commit-Position: refs/heads/main@{#1327773}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
afd93e5622
commit
fe310d6b61
content
@ -280,7 +280,8 @@
|
||||
base::FilePath filePath =
|
||||
base::apple::NSURLToFilePath([NSURL URLWithString:dropDestination]);
|
||||
filePath = filePath.Append(_downloadFileName);
|
||||
_host->DragPromisedFileTo(filePath, _dropData, _downloadURL, &filePath);
|
||||
_host->DragPromisedFileTo(filePath, _dropData, _downloadURL, _sourceOrigin,
|
||||
&filePath);
|
||||
|
||||
// The process of writing the file may have altered the value of
|
||||
// `filePath` if, say, an existing file at the drop site already had that
|
||||
|
@ -313,6 +313,7 @@ class WebContentsNSViewHostStub
|
||||
bool DragPromisedFileTo(const ::base::FilePath& file_path,
|
||||
const ::content::DropData& drop_data,
|
||||
const ::GURL& download_url,
|
||||
const ::url::Origin& source_origin,
|
||||
::base::FilePath* out_file_path) override {
|
||||
return false;
|
||||
}
|
||||
@ -320,6 +321,7 @@ class WebContentsNSViewHostStub
|
||||
void DragPromisedFileTo(const ::base::FilePath& file_path,
|
||||
const ::content::DropData& drop_data,
|
||||
const ::GURL& download_url,
|
||||
const ::url::Origin& source_origin,
|
||||
DragPromisedFileToCallback callback) override {}
|
||||
|
||||
void EndDrag(uint32_t drag_operation,
|
||||
|
@ -38,6 +38,7 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
DragDownloadFileUI(const GURL& url,
|
||||
const Referrer& referrer,
|
||||
const std::string& referrer_encoding,
|
||||
std::optional<url::Origin> initiator_origin,
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
OnCompleted on_completed)
|
||||
@ -45,6 +46,7 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
url_(url),
|
||||
referrer_(referrer),
|
||||
referrer_encoding_(referrer_encoding),
|
||||
initiator_origin_(initiator_origin),
|
||||
render_process_id_(render_process_id),
|
||||
render_frame_id_(render_frame_id) {
|
||||
DCHECK(on_completed_);
|
||||
@ -95,6 +97,7 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
params->set_referrer_policy(
|
||||
Referrer::ReferrerPolicyForUrlRequest(referrer_.policy));
|
||||
params->set_referrer_encoding(referrer_encoding_);
|
||||
params->set_initiator(initiator_origin_);
|
||||
params->set_callback(base::BindOnce(&DragDownloadFileUI::OnDownloadStarted,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
params->set_file_path(file_path);
|
||||
@ -174,6 +177,7 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
GURL url_;
|
||||
Referrer referrer_;
|
||||
std::string referrer_encoding_;
|
||||
std::optional<url::Origin> initiator_origin_;
|
||||
int render_process_id_;
|
||||
int render_frame_id_;
|
||||
raw_ptr<download::DownloadItem> download_item_ = nullptr;
|
||||
@ -187,13 +191,14 @@ DragDownloadFile::DragDownloadFile(const base::FilePath& file_path,
|
||||
const GURL& url,
|
||||
const Referrer& referrer,
|
||||
const std::string& referrer_encoding,
|
||||
std::optional<url::Origin> initiator_origin,
|
||||
WebContents* web_contents)
|
||||
: file_path_(file_path), file_(std::move(file)) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
RenderFrameHost* host = web_contents->GetPrimaryMainFrame();
|
||||
drag_ui_ = new DragDownloadFileUI(
|
||||
url, referrer, referrer_encoding, host->GetProcess()->GetID(),
|
||||
host->GetRoutingID(),
|
||||
url, referrer, referrer_encoding, initiator_origin,
|
||||
host->GetProcess()->GetID(), host->GetRoutingID(),
|
||||
base::BindOnce(&DragDownloadFile::DownloadCompleted,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
DCHECK(!file_path_.empty());
|
||||
|
@ -40,6 +40,7 @@ class CONTENT_EXPORT DragDownloadFile : public ui::DownloadFileProvider {
|
||||
const GURL& url,
|
||||
const Referrer& referrer,
|
||||
const std::string& referrer_encoding,
|
||||
std::optional<url::Origin> initiator_origin,
|
||||
WebContents* web_contents);
|
||||
|
||||
DragDownloadFile(const DragDownloadFile&) = delete;
|
||||
|
@ -2,14 +2,17 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "content/browser/download/drag_download_file.h"
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "content/browser/download/download_manager_impl.h"
|
||||
#include "content/browser/download/drag_download_file.h"
|
||||
#include "content/browser/download/drag_download_util.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
@ -100,9 +103,9 @@ IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_NetError) {
|
||||
ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
|
||||
Referrer referrer;
|
||||
std::string referrer_encoding;
|
||||
auto file = std::make_unique<DragDownloadFile>(name, base::File(), url,
|
||||
referrer, referrer_encoding,
|
||||
shell()->web_contents());
|
||||
auto file = std::make_unique<DragDownloadFile>(
|
||||
name, base::File(), url, referrer, referrer_encoding, std::nullopt,
|
||||
shell()->web_contents());
|
||||
scoped_refptr<MockDownloadFileObserver> observer(
|
||||
new MockDownloadFileObserver());
|
||||
EXPECT_CALL(*observer.get(), OnDownloadAborted())
|
||||
@ -119,9 +122,9 @@ IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_Complete) {
|
||||
GURL url = embedded_test_server()->GetURL("/download/download-test.lib");
|
||||
Referrer referrer;
|
||||
std::string referrer_encoding;
|
||||
auto file = std::make_unique<DragDownloadFile>(name, base::File(), url,
|
||||
referrer, referrer_encoding,
|
||||
shell()->web_contents());
|
||||
auto file = std::make_unique<DragDownloadFile>(
|
||||
name, base::File(), url, referrer, referrer_encoding, std::nullopt,
|
||||
shell()->web_contents());
|
||||
scoped_refptr<MockDownloadFileObserver> observer(
|
||||
new MockDownloadFileObserver());
|
||||
EXPECT_CALL(*observer.get(), OnDownloadCompleted(_))
|
||||
@ -132,15 +135,48 @@ IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_Complete) {
|
||||
RunUntilSucceed();
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_Initiator) {
|
||||
base::FilePath name(
|
||||
downloads_directory().AppendASCII("DragDownloadFileTest_Initiator.txt"));
|
||||
GURL url = embedded_test_server()->GetURL("/echoheader?sec-fetch-site");
|
||||
url::Origin initiator =
|
||||
url::Origin::Create(GURL("https://initiator.example.com"));
|
||||
Referrer referrer;
|
||||
std::string referrer_encoding;
|
||||
auto file = std::make_unique<DragDownloadFile>(
|
||||
name, base::File(), url, referrer, referrer_encoding, initiator,
|
||||
shell()->web_contents());
|
||||
base::FilePath downloaded_path;
|
||||
scoped_refptr<MockDownloadFileObserver> observer(
|
||||
new MockDownloadFileObserver());
|
||||
EXPECT_CALL(*observer.get(), OnDownloadCompleted(_))
|
||||
.WillOnce([&](const base::FilePath& file_path) {
|
||||
downloaded_path = file_path;
|
||||
this->Succeed();
|
||||
});
|
||||
ON_CALL(*observer.get(), OnDownloadAborted())
|
||||
.WillByDefault(InvokeWithoutArgs(this, &DragDownloadFileTest::FailFast));
|
||||
file->Start(observer.get());
|
||||
RunUntilSucceed();
|
||||
|
||||
std::string actual_sec_fetch_site_value;
|
||||
{
|
||||
base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
ASSERT_TRUE(
|
||||
base::ReadFileToString(downloaded_path, &actual_sec_fetch_site_value));
|
||||
}
|
||||
EXPECT_EQ("cross-site", actual_sec_fetch_site_value);
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_ClosePage) {
|
||||
base::FilePath name(
|
||||
downloads_directory().AppendASCII("DragDownloadFileTest_Complete.txt"));
|
||||
GURL url = embedded_test_server()->GetURL("/download/download-test.lib");
|
||||
Referrer referrer;
|
||||
std::string referrer_encoding;
|
||||
auto file = std::make_unique<DragDownloadFile>(name, base::File(), url,
|
||||
referrer, referrer_encoding,
|
||||
shell()->web_contents());
|
||||
auto file = std::make_unique<DragDownloadFile>(
|
||||
name, base::File(), url, referrer, referrer_encoding, std::nullopt,
|
||||
shell()->web_contents());
|
||||
scoped_refptr<MockDownloadFileObserver> observer(
|
||||
new MockDownloadFileObserver());
|
||||
ON_CALL(*observer.get(), OnDownloadAborted())
|
||||
|
@ -232,7 +232,7 @@ void PrepareDragForDownload(const DropData& drop_data,
|
||||
auto download_file = std::make_unique<DragDownloadFile>(
|
||||
download_path, base::File(), download_url,
|
||||
Referrer(page_url, drop_data.referrer_policy), page_encoding,
|
||||
web_contents);
|
||||
provider->GetRendererTaintedOrigin(), web_contents);
|
||||
ui::DownloadFileInfo file_download(base::FilePath(),
|
||||
std::move(download_file));
|
||||
provider->SetDownloadFileInfo(&file_download);
|
||||
|
@ -169,6 +169,7 @@ class WebContentsViewMac : public WebContentsView,
|
||||
bool DragPromisedFileTo(const base::FilePath& file_path,
|
||||
const DropData& drop_data,
|
||||
const GURL& download_url,
|
||||
const url::Origin& source_origin,
|
||||
base::FilePath* out_file_path) override;
|
||||
void EndDrag(uint32_t drag_opeation,
|
||||
const gfx::PointF& local_point,
|
||||
@ -184,6 +185,7 @@ class WebContentsViewMac : public WebContentsView,
|
||||
void DragPromisedFileTo(const base::FilePath& file_path,
|
||||
const DropData& drop_data,
|
||||
const GURL& download_url,
|
||||
const url::Origin& source_origin,
|
||||
DragPromisedFileToCallback callback) override;
|
||||
|
||||
// Return the list of child RenderWidgetHostViewMacs. This will remove any
|
||||
|
@ -521,6 +521,7 @@ bool WebContentsViewMac::PerformDragOperation(DraggingInfoPtr dragging_info,
|
||||
bool WebContentsViewMac::DragPromisedFileTo(const base::FilePath& file_path,
|
||||
const DropData& drop_data,
|
||||
const GURL& download_url,
|
||||
const url::Origin& source_origin,
|
||||
base::FilePath* out_file_path) {
|
||||
*out_file_path = file_path;
|
||||
// This is called by -namesOfPromisedFilesDroppedAtDestination, which is
|
||||
@ -539,7 +540,7 @@ bool WebContentsViewMac::DragPromisedFileTo(const base::FilePath& file_path,
|
||||
*out_file_path, std::move(file), download_url,
|
||||
content::Referrer(web_contents_->GetLastCommittedURL(),
|
||||
drop_data.referrer_policy),
|
||||
web_contents_->GetEncoding(), web_contents_);
|
||||
web_contents_->GetEncoding(), source_origin, web_contents_);
|
||||
|
||||
DragDownloadFile* downloader = drag_file_downloader.get();
|
||||
// The finalizer will take care of closing and deletion.
|
||||
@ -616,9 +617,11 @@ void WebContentsViewMac::DragPromisedFileTo(
|
||||
const base::FilePath& file_path,
|
||||
const DropData& drop_data,
|
||||
const GURL& download_url,
|
||||
const url::Origin& source_origin,
|
||||
DragPromisedFileToCallback callback) {
|
||||
base::FilePath actual_file_path;
|
||||
DragPromisedFileTo(file_path, drop_data, download_url, &actual_file_path);
|
||||
DragPromisedFileTo(file_path, drop_data, download_url, source_origin,
|
||||
&actual_file_path);
|
||||
std::move(callback).Run(actual_file_path);
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,8 @@ interface WebContentsNSViewHost {
|
||||
[Sync]
|
||||
DragPromisedFileTo(mojo_base.mojom.FilePath file_path,
|
||||
content.mojom.DropData drop_data,
|
||||
url.mojom.Url download_url) =>
|
||||
url.mojom.Url download_url,
|
||||
url.mojom.Origin source_origin) =>
|
||||
(mojo_base.mojom.FilePath file_path);
|
||||
|
||||
// Called in to the -draggedImage: method being called on the NSView.
|
||||
|
Reference in New Issue
Block a user