Use request_initiator in quarantine
When source_url cannot be used (e.g. data:// URLs), try using the request_initiator as HostUrl instead. Bug: 351165321 Change-Id: I0c481a2da634891abaf18d7795cd911d04aec1ff Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5824218 Commit-Queue: Daniel Rubery <drubery@chromium.org> Reviewed-by: Ayu Ishii <ayui@chromium.org> Reviewed-by: Will Harris <wfh@chromium.org> Reviewed-by: Derek Schuff <dschuff@chromium.org> Reviewed-by: Min Qin <qinmin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1352856}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
abefe04fdc
commit
4fbe682556
chrome/browser/media_galleries/fileapi
components
download
internal
services
content/browser
@ -42,7 +42,8 @@ void ScanFile(
|
||||
|
||||
if (quarantine_remote) {
|
||||
quarantine_remote->QuarantineFile(
|
||||
dest_platform_path, GURL(), GURL(), std::string(),
|
||||
dest_platform_path, GURL(), GURL(), /*request_initiator=*/std::nullopt,
|
||||
std::string(),
|
||||
base::BindOnce(&OnFileQuarantined, std::move(result_callback)));
|
||||
} else {
|
||||
std::move(result_callback).Run(base::File::FILE_OK);
|
||||
|
@ -8,6 +8,7 @@ include_rules = [
|
||||
"+components/safe_browsing/buildflags.h",
|
||||
"+components/safe_browsing/content/common",
|
||||
"+components/services/quarantine/quarantine.h",
|
||||
"+components/services/quarantine/public",
|
||||
"+components/ukm/test_ukm_recorder.h",
|
||||
"+crypto",
|
||||
"+mojo/public/c/system",
|
||||
|
@ -650,7 +650,7 @@ void BaseFile::AnnotateWithSourceInformation(
|
||||
authority_url, referrer_url));
|
||||
|
||||
quarantine_service_->QuarantineFile(
|
||||
full_path_, authority_url, referrer_url, client_guid,
|
||||
full_path_, authority_url, referrer_url, request_initiator, client_guid,
|
||||
base::BindOnce(&BaseFile::OnFileQuarantined,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "components/download/public/common/download_file_impl.h"
|
||||
#include "components/download/public/common/download_interrupt_reasons.h"
|
||||
#include "components/download/public/common/mock_input_stream.h"
|
||||
#include "components/services/quarantine/public/mojom/quarantine.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
@ -44,11 +46,13 @@
|
||||
using ::testing::_;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::DoAll;
|
||||
using ::testing::Eq;
|
||||
using ::testing::InSequence;
|
||||
using ::testing::Return;
|
||||
using ::testing::Sequence;
|
||||
using ::testing::SetArgPointee;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::WithArg;
|
||||
|
||||
namespace download {
|
||||
namespace {
|
||||
@ -139,6 +143,18 @@ class TestDownloadFileImpl : public DownloadFileImpl {
|
||||
#endif
|
||||
};
|
||||
|
||||
class MockQuarantine : public quarantine::mojom::Quarantine {
|
||||
public:
|
||||
MOCK_METHOD(void,
|
||||
QuarantineFile,
|
||||
(const base::FilePath& full_path,
|
||||
const GURL& source_url,
|
||||
const GURL& referrer_url,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
quarantine::mojom::Quarantine::QuarantineFileCallback callback));
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class DownloadFileTest : public testing::Test {
|
||||
@ -164,7 +180,8 @@ class DownloadFileTest : public testing::Test {
|
||||
additional_streams_(std::vector<raw_ptr<StrictMock<MockInputStream>>>{
|
||||
nullptr, nullptr}),
|
||||
bytes_(-1),
|
||||
bytes_per_sec_(-1) {}
|
||||
bytes_per_sec_(-1),
|
||||
quarantine_remote_(&quarantine_) {}
|
||||
|
||||
~DownloadFileTest() override {}
|
||||
|
||||
@ -187,6 +204,12 @@ class DownloadFileTest : public testing::Test {
|
||||
EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _, _))
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(Invoke(this, &DownloadFileTest::SetUpdateDownloadInfo));
|
||||
ON_CALL(quarantine_, QuarantineFile(_, _, _, _, _, _))
|
||||
.WillByDefault(WithArg<5>(
|
||||
[](quarantine::mojom::Quarantine::QuarantineFileCallback callback) {
|
||||
std::move(callback).Run(
|
||||
quarantine::mojom::QuarantineFileResult::OK);
|
||||
}));
|
||||
bool result = download_dir_.CreateUniqueTempDir();
|
||||
CHECK(result);
|
||||
}
|
||||
@ -425,9 +448,18 @@ class DownloadFileTest : public testing::Test {
|
||||
break;
|
||||
|
||||
case RENAME_AND_ANNOTATE:
|
||||
// We cannot rebind a mojo::Remote without resetting it. The
|
||||
// real implementation binds a new Remote on every call to
|
||||
// RenameAndAnnotate, but it's simpler to reuse
|
||||
// `quarantine_remote_` in tests.
|
||||
quarantine_remote_.reset();
|
||||
download_file_->RenameAndAnnotate(
|
||||
full_path, "12345678-ABCD-1234-DCBA-123456789ABC", GURL(), GURL(),
|
||||
/*request_initiator=*/std::nullopt, mojo::NullRemote(),
|
||||
full_path, "12345678-ABCD-1234-DCBA-123456789ABC",
|
||||
GURL("https://source.example.com/"),
|
||||
GURL("https://referrer.example.com/"),
|
||||
/*request_initiator=*/
|
||||
url::Origin::Create(GURL("https://initiator.example.com/")),
|
||||
quarantine_remote_.BindNewPipeAndPassRemote(),
|
||||
std::move(completion_callback));
|
||||
break;
|
||||
}
|
||||
@ -527,6 +559,8 @@ class DownloadFileTest : public testing::Test {
|
||||
// Keep track of what data should be saved to the disk file.
|
||||
std::string expected_data_;
|
||||
|
||||
MockQuarantine quarantine_;
|
||||
|
||||
private:
|
||||
void SetRenameResult(base::OnceClosure closure,
|
||||
DownloadInterruptReason* reason_p,
|
||||
@ -540,6 +574,8 @@ class DownloadFileTest : public testing::Test {
|
||||
std::move(closure).Run();
|
||||
}
|
||||
|
||||
mojo::Receiver<quarantine::mojom::Quarantine> quarantine_remote_;
|
||||
|
||||
base::test::TaskEnvironment task_environment_;
|
||||
};
|
||||
|
||||
@ -1274,4 +1310,31 @@ TEST_F(DownloadFileTest, SecondStreamReadsOffsetWrittenByFirst) {
|
||||
DestroyDownloadFile(0, false);
|
||||
}
|
||||
|
||||
TEST_F(DownloadFileTest, PropagatesUrlAndInitiatorToQuarantine) {
|
||||
ASSERT_TRUE(CreateDownloadFile(true));
|
||||
base::FilePath initial_path(download_file_->FullPath());
|
||||
base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1"));
|
||||
|
||||
EXPECT_CALL(
|
||||
quarantine_,
|
||||
QuarantineFile(
|
||||
_, GURL("https://source.example.com/"),
|
||||
GURL("https://referrer.example.com"),
|
||||
Eq(url::Origin::Create(GURL("https://initiator.example.com/"))), _,
|
||||
_))
|
||||
.WillOnce(WithArg<5>(
|
||||
[](quarantine::mojom::Quarantine::QuarantineFileCallback callback) {
|
||||
std::move(callback).Run(
|
||||
quarantine::mojom::QuarantineFileResult::OK);
|
||||
}));
|
||||
base::FilePath new_path;
|
||||
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
|
||||
RenameAndAnnotate(path_1, &new_path));
|
||||
EXPECT_EQ(path_1.value(), new_path.value());
|
||||
|
||||
FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
|
||||
base::RunLoop().RunUntilIdle();
|
||||
DestroyDownloadFile(0);
|
||||
}
|
||||
|
||||
} // namespace download
|
||||
|
@ -11,5 +11,6 @@ mojom("mojom") {
|
||||
"//mojo/public/mojom/base",
|
||||
"//sandbox/policy/mojom",
|
||||
"//url/mojom:url_mojom_gurl",
|
||||
"//url/mojom:url_mojom_origin",
|
||||
]
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ module quarantine.mojom;
|
||||
import "mojo/public/mojom/base/file_path.mojom";
|
||||
import "sandbox/policy/mojom/sandbox.mojom";
|
||||
import "url/mojom/url.mojom";
|
||||
import "url/mojom/origin.mojom";
|
||||
|
||||
enum QuarantineFileResult {
|
||||
OK, // Success.
|
||||
@ -29,9 +30,15 @@ enum QuarantineFileResult {
|
||||
[ServiceSandbox=sandbox.mojom.Sandbox.kNoSandbox]
|
||||
interface Quarantine {
|
||||
|
||||
// Quarantine a file that was downloaded from the internet. This method
|
||||
// will apply platform-dependent annotations to the file to indicate that
|
||||
// it came from the internet, and what URL(s) led to the file. For more
|
||||
// details, see the documentation in
|
||||
// //components/services/quarantine/quarantine.h.
|
||||
QuarantineFile(mojo_base.mojom.FilePath full_path,
|
||||
url.mojom.Url source_url,
|
||||
url.mojom.Url referrer_url,
|
||||
url.mojom.Origin? request_initiator,
|
||||
string client_guid)
|
||||
=> (QuarantineFileResult result);
|
||||
};
|
||||
|
@ -13,6 +13,7 @@ namespace quarantine {
|
||||
void QuarantineFile(const base::FilePath& file,
|
||||
const GURL& source_url,
|
||||
const GURL& referrer_url,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
mojom::Quarantine::QuarantineFileCallback callback) {
|
||||
std::move(callback).Run(QuarantineFileResult::OK);
|
||||
|
@ -58,6 +58,9 @@ using mojom::QuarantineFileResult;
|
||||
// |source_url|: URL from which the file content was downloaded. This is empty
|
||||
// for off-the-record download.
|
||||
// |referrer_url|: Referring URL. This is empty for off-the-record download.
|
||||
// `request_initiator`: Origin initiating the request. This is meant to
|
||||
// replace the source URL when the source URL is not suitable for use in an
|
||||
// annotation (e.g. a data URL).
|
||||
// |client_guid|: Only used on Windows. Identifies the client application
|
||||
// that downloaded the file.
|
||||
// |callback|: Will be called with the quarantine result on completion.
|
||||
@ -70,6 +73,7 @@ using mojom::QuarantineFileResult;
|
||||
void QuarantineFile(const base::FilePath& file,
|
||||
const GURL& source_url,
|
||||
const GURL& referrer_url,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
mojom::Quarantine::QuarantineFileCallback callback);
|
||||
|
||||
|
@ -27,6 +27,7 @@ void OnFileAdded(mojom::Quarantine::QuarantineFileCallback callback,
|
||||
void QuarantineFile(const base::FilePath& file,
|
||||
const GURL& source_url_unsafe,
|
||||
const GURL& referrer_url_unsafe,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
mojom::Quarantine::QuarantineFileCallback callback) {
|
||||
if (!chromeos::DlpClient::Get() || !chromeos::DlpClient::Get()->IsAlive()) {
|
||||
|
@ -34,6 +34,7 @@ void QuarantineImpl::QuarantineFile(
|
||||
const base::FilePath& full_path,
|
||||
const GURL& source_url,
|
||||
const GURL& referrer_url,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
mojom::Quarantine::QuarantineFileCallback callback) {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
@ -50,7 +51,7 @@ void QuarantineImpl::QuarantineFile(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
&quarantine::QuarantineFile, full_path, source_url, referrer_url,
|
||||
client_guid,
|
||||
request_initiator, client_guid,
|
||||
base::BindOnce(&ReplyToCallback,
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault(),
|
||||
std::move(callback))));
|
||||
|
@ -33,6 +33,7 @@ class QuarantineImpl : public mojom::Quarantine {
|
||||
const base::FilePath& full_path,
|
||||
const GURL& source_url,
|
||||
const GURL& referrer_url,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
mojom::Quarantine::QuarantineFileCallback callback) override;
|
||||
|
||||
|
@ -96,6 +96,7 @@ bool AddOriginMetadataToFile(const base::FilePath& file,
|
||||
void QuarantineFile(const base::FilePath& file,
|
||||
const GURL& source_url_unsafe,
|
||||
const GURL& referrer_url_unsafe,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
mojom::Quarantine::QuarantineFileCallback callback) {
|
||||
if (!base::PathExists(file)) {
|
||||
@ -111,6 +112,9 @@ void QuarantineFile(const base::FilePath& file,
|
||||
|
||||
GURL source_url = SanitizeUrlForQuarantine(source_url_unsafe);
|
||||
GURL referrer_url = SanitizeUrlForQuarantine(referrer_url_unsafe);
|
||||
if (source_url.is_empty() && request_initiator.has_value()) {
|
||||
source_url = SanitizeUrlForQuarantine(request_initiator->GetURL());
|
||||
}
|
||||
|
||||
// Don't consider it an error if we fail to add origin metadata.
|
||||
AddOriginMetadataToFile(file, source_url, referrer_url);
|
||||
|
@ -26,9 +26,11 @@
|
||||
namespace quarantine {
|
||||
namespace {
|
||||
|
||||
void CheckQuarantineResult(QuarantineFileResult result,
|
||||
void CheckQuarantineResult(base::OnceClosure quit_closure,
|
||||
QuarantineFileResult result,
|
||||
QuarantineFileResult expected_result) {
|
||||
EXPECT_EQ(expected_result, result);
|
||||
std::move(quit_closure).Run();
|
||||
}
|
||||
|
||||
class QuarantineMacTest : public testing::Test {
|
||||
@ -69,23 +71,37 @@ class QuarantineMacTest : public testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(QuarantineMacTest, CheckMetadataSetCorrectly) {
|
||||
QuarantineFile(
|
||||
test_file_, source_url_, referrer_url_, "",
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
base::RunLoop run_loop;
|
||||
QuarantineFile(test_file_, source_url_, referrer_url_,
|
||||
/*request_initiator=*/std::nullopt, "",
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, referrer_url_));
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, SetMetadataMultipleTimes) {
|
||||
GURL dummy_url("http://www.dummy.example.com");
|
||||
QuarantineFile(
|
||||
test_file_, source_url_, referrer_url_, "",
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
QuarantineFile(
|
||||
test_file_, dummy_url, dummy_url, "",
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, referrer_url_));
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
QuarantineFile(
|
||||
test_file_, source_url_, referrer_url_,
|
||||
/*request_initiator=*/std::nullopt, "",
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
{
|
||||
base::RunLoop run_loop;
|
||||
GURL dummy_url("http://www.dummy.example.com");
|
||||
QuarantineFile(
|
||||
test_file_, dummy_url, dummy_url,
|
||||
/*request_initiator=*/std::nullopt, "",
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, referrer_url_));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, IsFileQuarantined_NoFile) {
|
||||
@ -99,20 +115,24 @@ TEST_F(QuarantineMacTest, IsFileQuarantined_NoAnnotationsOnFile) {
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, IsFileQuarantined_SourceUrlOnly) {
|
||||
QuarantineFile(
|
||||
test_file_, source_url_, GURL(), std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
base::RunLoop run_loop;
|
||||
QuarantineFile(test_file_, source_url_, GURL(),
|
||||
/*request_initiator=*/std::nullopt, std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, GURL()));
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, GURL(), GURL()));
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, GURL(), referrer_url_));
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, IsFileQuarantined_FullMetadata) {
|
||||
QuarantineFile(
|
||||
test_file_, source_url_, referrer_url_, std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
base::RunLoop run_loop;
|
||||
QuarantineFile(test_file_, source_url_, referrer_url_,
|
||||
/*request_initiator=*/std::nullopt, std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, GURL(), GURL()));
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, GURL()));
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, referrer_url_));
|
||||
@ -120,24 +140,28 @@ TEST_F(QuarantineMacTest, IsFileQuarantined_FullMetadata) {
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, IsFileQuarantined_Sanitize) {
|
||||
base::RunLoop run_loop;
|
||||
GURL host_url{"https://user:pass@example.com/foo/bar?x#y"};
|
||||
GURL host_url_clean{"https://example.com/foo/bar?x#y"};
|
||||
GURL referrer_url{"https://user:pass@example.com/foo/index?x#y"};
|
||||
GURL referrer_url_clean{"https://example.com/foo/index?x#y"};
|
||||
|
||||
QuarantineFile(
|
||||
test_file_, host_url, referrer_url, std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
QuarantineFile(test_file_, host_url, referrer_url,
|
||||
/*request_initiator=*/std::nullopt, std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
EXPECT_TRUE(
|
||||
IsFileQuarantined(test_file_, host_url_clean, referrer_url_clean));
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, IsFileQuarantined_AgentBundleIdentifier) {
|
||||
QuarantineFile(
|
||||
test_file_, source_url_, referrer_url_, "",
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
base::RunLoop run_loop;
|
||||
QuarantineFile(test_file_, source_url_, referrer_url_,
|
||||
/*request_initiator=*/std::nullopt, "",
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
|
||||
NSDictionary* properties = GetQuarantineProperties(test_file_);
|
||||
ASSERT_TRUE(properties);
|
||||
@ -157,10 +181,12 @@ TEST_F(QuarantineMacTest, IsFileQuarantined_AgentBundleIdentifier) {
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, NoWhereFromsKeyIfNoURLs) {
|
||||
QuarantineFile(
|
||||
test_file_, GURL(), GURL(), std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
base::RunLoop run_loop;
|
||||
QuarantineFile(test_file_, GURL(), GURL(), /*request_initiator=*/std::nullopt,
|
||||
std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
|
||||
NSString* file_path = base::apple::FilePathToNSString(test_file_);
|
||||
ASSERT_NE(nullptr, file_path);
|
||||
@ -178,5 +204,18 @@ TEST_F(QuarantineMacTest, NoWhereFromsKeyIfNoURLs) {
|
||||
EXPECT_FALSE(attr);
|
||||
}
|
||||
|
||||
TEST_F(QuarantineMacTest, RequestInitiatorReplacesSourceUrl) {
|
||||
base::RunLoop run_loop;
|
||||
QuarantineFile(test_file_, GURL("data://text/html,payload"), referrer_url_,
|
||||
/*request_initiator=*/
|
||||
url::Origin::Create(GURL("http://www.source.example.com/")),
|
||||
"",
|
||||
base::BindOnce(&CheckQuarantineResult, run_loop.QuitClosure(),
|
||||
QuarantineFileResult::OK));
|
||||
run_loop.Run();
|
||||
EXPECT_TRUE(IsFileQuarantined(
|
||||
test_file_, GURL("http://www.source.example.com/"), referrer_url_));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace quarantine
|
||||
|
@ -59,7 +59,8 @@ TEST_F(QuarantineServiceTest, QuarantineFile) {
|
||||
|
||||
base::RunLoop run_loop;
|
||||
quarantine_->QuarantineFile(
|
||||
test_file, GURL(kInternetURL), GURL(kInternetReferrerURL), std::string(),
|
||||
test_file, GURL(kInternetURL), GURL(kInternetReferrerURL),
|
||||
/*request_initiator=*/std::nullopt, std::string(),
|
||||
base::BindOnce(&QuarantineServiceTest::OnFileQuarantined,
|
||||
base::Unretained(this), test_file,
|
||||
run_loop.QuitClosure()));
|
||||
|
@ -64,7 +64,8 @@ class QuarantineTest : public testing::Test {
|
||||
TEST_F(QuarantineTest, FileCanBeOpenedForReadAfterAnnotation) {
|
||||
base::FilePath test_file = GetTestFilePath();
|
||||
QuarantineFile(
|
||||
test_file, GURL(kInternetURL), GURL(kInternetReferrerURL), kTestGUID,
|
||||
test_file, GURL(kInternetURL), GURL(kInternetReferrerURL),
|
||||
/*request_initiator=*/std::nullopt, kTestGUID,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -76,7 +77,7 @@ TEST_F(QuarantineTest, FileCanBeOpenedForReadAfterAnnotation) {
|
||||
TEST_F(QuarantineTest, FileCanBeAnnotatedWithNoGUID) {
|
||||
QuarantineFile(
|
||||
GetTestFilePath(), GURL(kInternetURL), GURL(kInternetReferrerURL),
|
||||
std::string(),
|
||||
/*request_initiator=*/std::nullopt, std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
}
|
||||
|
@ -225,6 +225,7 @@ QuarantineFileResult SetInternetZoneIdentifierDirectly(
|
||||
void QuarantineFile(const base::FilePath& file,
|
||||
const GURL& source_url_unsafe,
|
||||
const GURL& referrer_url_unsafe,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
mojom::Quarantine::QuarantineFileCallback callback) {
|
||||
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
|
||||
@ -245,6 +246,10 @@ void QuarantineFile(const base::FilePath& file,
|
||||
}
|
||||
|
||||
GURL source_url = SanitizeUrlForQuarantine(source_url_unsafe);
|
||||
if (source_url.is_empty() && request_initiator.has_value()) {
|
||||
source_url = SanitizeUrlForQuarantine(request_initiator->GetURL());
|
||||
}
|
||||
|
||||
GURL referrer_url = SanitizeUrlForQuarantine(referrer_url_unsafe);
|
||||
|
||||
if (file_size == 0 || IsEqualGUID(guid, GUID_NULL)) {
|
||||
|
@ -187,7 +187,7 @@ class QuarantineWinTest : public ::testing::Test {
|
||||
TEST_F(QuarantineWinTest, MissingFile) {
|
||||
QuarantineFile(GetTempDir().AppendASCII("does-not-exist.exe"),
|
||||
GURL(kDummySourceUrl), GURL(kDummyReferrerUrl),
|
||||
kDummyClientGuid,
|
||||
/*request_initiator=*/std::nullopt, kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult,
|
||||
QuarantineFileResult::FILE_MISSING));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
@ -210,7 +210,8 @@ TEST_F(QuarantineWinTest, LocalFile_DependsOnLocalConfig) {
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
|
||||
QuarantineFile(
|
||||
test_file, GURL(source_url), GURL(), kDummyClientGuid,
|
||||
test_file, GURL(source_url), GURL(), /*request_initiator=*/std::nullopt,
|
||||
kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -237,7 +238,8 @@ TEST_F(QuarantineWinTest, DownloadedFile_DependsOnLocalConfig) {
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
|
||||
QuarantineFile(
|
||||
test_file, GURL(source_url), GURL(), kDummyClientGuid,
|
||||
test_file, GURL(source_url), GURL(), /*request_initiator=*/std::nullopt,
|
||||
kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -270,7 +272,7 @@ TEST_F(QuarantineWinTest, UnsafeReferrer_DependsOnLocalConfig) {
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
QuarantineFile(
|
||||
test_file, GURL("http://example.com/good"), GURL(referrer_url),
|
||||
kDummyClientGuid,
|
||||
/*request_initiator=*/std::nullopt, kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -293,7 +295,8 @@ TEST_F(QuarantineWinTest, EmptySource_DependsOnLocalConfig) {
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
|
||||
QuarantineFile(
|
||||
test_file, GURL(), GURL(), kDummyClientGuid,
|
||||
test_file, GURL(), GURL(), /*request_initiator=*/std::nullopt,
|
||||
kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -314,7 +317,8 @@ TEST_F(QuarantineWinTest, EmptyFile) {
|
||||
ASSERT_TRUE(base::WriteFile(test_file, ""));
|
||||
|
||||
QuarantineFile(
|
||||
test_file, net::FilePathToFileURL(test_file), GURL(), kDummyClientGuid,
|
||||
test_file, net::FilePathToFileURL(test_file), GURL(),
|
||||
/*request_initiator=*/std::nullopt, kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -336,7 +340,8 @@ TEST_F(QuarantineWinTest, NoClientGuid) {
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
|
||||
QuarantineFile(
|
||||
test_file, net::FilePathToFileURL(test_file), GURL(), std::string(),
|
||||
test_file, net::FilePathToFileURL(test_file), GURL(),
|
||||
/*request_initiator=*/std::nullopt, std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -359,7 +364,8 @@ TEST_F(QuarantineWinTest, SuperLongURL) {
|
||||
std::string source_url("http://example.com/");
|
||||
source_url.append(INTERNET_MAX_URL_LENGTH * 2, 'a');
|
||||
QuarantineFile(
|
||||
test_file, GURL(source_url), GURL(), std::string(),
|
||||
test_file, GURL(source_url), GURL(), /*request_initiator=*/std::nullopt,
|
||||
std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -380,7 +386,8 @@ TEST_F(QuarantineWinTest, TrustedSite) {
|
||||
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
QuarantineFile(
|
||||
test_file, source_url, GURL(), kDummyClientGuid,
|
||||
test_file, source_url, GURL(), /*request_initiator=*/std::nullopt,
|
||||
kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -398,7 +405,8 @@ TEST_F(QuarantineWinTest, RestrictedSite) {
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
|
||||
// Files from a restricted site are deleted.
|
||||
QuarantineFile(test_file, source_url, GURL(), kDummyClientGuid,
|
||||
QuarantineFile(test_file, source_url, GURL(),
|
||||
/*request_initiator=*/std::nullopt, kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult,
|
||||
QuarantineFileResult::BLOCKED_BY_POLICY));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
@ -417,7 +425,8 @@ TEST_F(QuarantineWinTest, TrustedSite_AlreadyQuarantined) {
|
||||
// Ensure the file already contains a zone identifier.
|
||||
ASSERT_TRUE(AddInternetZoneIdentifierDirectly(test_file));
|
||||
QuarantineFile(
|
||||
test_file, source_url, GURL(), kDummyClientGuid,
|
||||
test_file, source_url, GURL(), /*request_initiator=*/std::nullopt,
|
||||
kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -439,7 +448,8 @@ TEST_F(QuarantineWinTest, RestrictedSite_AlreadyQuarantined) {
|
||||
ASSERT_TRUE(AddInternetZoneIdentifierDirectly(test_file));
|
||||
|
||||
// Files from a restricted site are deleted.
|
||||
QuarantineFile(test_file, source_url, GURL(), kDummyClientGuid,
|
||||
QuarantineFile(test_file, source_url, GURL(),
|
||||
/*request_initiator=*/std::nullopt, kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult,
|
||||
QuarantineFileResult::BLOCKED_BY_POLICY));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
@ -463,7 +473,8 @@ TEST_F(QuarantineWinTest, MetaData_ApplyMOTW_Directly) {
|
||||
|
||||
// An invalid GUID will cause QuarantineFile() to apply the MOTW directly.
|
||||
QuarantineFile(
|
||||
test_file, host_url, referrer_url, std::string(),
|
||||
test_file, host_url, referrer_url, /*request_initiator=*/std::nullopt,
|
||||
std::string(),
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
@ -484,11 +495,26 @@ TEST_F(QuarantineWinTest, MetaData_InvokeAS) {
|
||||
base::StrCat({"https://", GetInternetSite(), "/folder/index?x#y"}));
|
||||
|
||||
QuarantineFile(
|
||||
test_file, host_url, referrer_url, kDummyClientGuid,
|
||||
test_file, host_url, referrer_url, /*request_initiator=*/std::nullopt,
|
||||
kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file, host_url_clean, referrer_url_clean));
|
||||
}
|
||||
|
||||
TEST_F(QuarantineWinTest, RequestInitiatorReplacesSourceUrl) {
|
||||
base::FilePath test_file = GetTempDir().AppendASCII("foo.exe");
|
||||
ASSERT_TRUE(CreateFile(test_file));
|
||||
|
||||
GURL host_url(base::StrCat({"https://", GetInternetSite(), "/"}));
|
||||
QuarantineFile(
|
||||
test_file, GURL("data://text/html,payload"), GURL(),
|
||||
url::Origin::Create(host_url), kDummyClientGuid,
|
||||
base::BindOnce(&CheckQuarantineResult, QuarantineFileResult::OK));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_TRUE(IsFileQuarantined(test_file, host_url, GURL()));
|
||||
}
|
||||
|
||||
} // namespace quarantine
|
||||
|
@ -67,6 +67,7 @@ class MockQuarantine : public quarantine::mojom::Quarantine {
|
||||
void QuarantineFile(const base::FilePath& full_path,
|
||||
const GURL& source_url,
|
||||
const GURL& referrer_url,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
QuarantineFileCallback callback) override {
|
||||
paths.push_back(full_path);
|
||||
|
@ -344,6 +344,9 @@ void FileSystemAccessSafeMoveHelper::DidFileDoQuarantine(
|
||||
quarantine::mojom::Quarantine* raw_quarantine = quarantine_remote.get();
|
||||
raw_quarantine->QuarantineFile(
|
||||
target_url.path(), authority_url, referrer_url,
|
||||
// TODO(crbug.com/351165321): Consider propagating request_initiator
|
||||
// information here.
|
||||
/*request_initiator=*/std::nullopt,
|
||||
GetContentClient()
|
||||
->browser()
|
||||
->GetApplicationClientGUIDForQuarantineCheck(),
|
||||
|
@ -54,6 +54,7 @@ class MockQuarantine : public quarantine::mojom::Quarantine {
|
||||
void QuarantineFile(const base::FilePath& full_path,
|
||||
const GURL& source_url,
|
||||
const GURL& referrer_url,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
const std::string& client_guid,
|
||||
QuarantineFileCallback callback) override {
|
||||
paths.push_back(full_path);
|
||||
|
@ -482,7 +482,7 @@ void PepperFileIOHost::OnLocalFileOpened(
|
||||
quarantine::mojom::Quarantine* raw_quarantine = quarantine_remote.get();
|
||||
raw_quarantine->QuarantineFile(
|
||||
path, browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()),
|
||||
GURL(), std::string(),
|
||||
GURL(), /*request_initiator=*/std::nullopt, std::string(),
|
||||
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
|
||||
base::BindOnce(&PepperFileIOHost::OnLocalFileQuarantined,
|
||||
weak_ptr_factory_.GetWeakPtr(), reply_context, path,
|
||||
|
Reference in New Issue
Block a user