Commit 0efba143 authored by Daniel Rubery's avatar Daniel Rubery Committed by Commit Bot

Extend referrer chain for SBER users to 5 gestures

Based on some example campaigns for which chrome sync history won't be
useful, extend the maximum number of gestures in a referrer chain to
5 gestures. We can then evaluate how useful the extra data is, and
possible extend the maximum gestures for all users.

Bug: 864266
Change-Id: Idbcc2e07f7593a90f05ba07a2e1ef0c2a1be757b
Reviewed-on: https://chromium-review.googlesource.com/c/1287041
Commit-Queue: Daniel Rubery <drubery@chromium.org>
Reviewed-by: default avatarJialiu Lin <jialiul@chromium.org>
Reviewed-by: default avatarVarun Khaneja <vakh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600883}
parent 6e195006
...@@ -44,6 +44,7 @@ const double kWhitelistDownloadSampleRate = 0.01; ...@@ -44,6 +44,7 @@ const double kWhitelistDownloadSampleRate = 0.01;
// The number of user gestures we trace back for download attribution. // The number of user gestures we trace back for download attribution.
const int kDownloadAttributionUserGestureLimit = 2; const int kDownloadAttributionUserGestureLimit = 2;
const int kDownloadAttributionUserGestureLimitForExtendedReporting = 5;
void AddEventUrlToReferrerChain(const download::DownloadItem& item, void AddEventUrlToReferrerChain(const download::DownloadItem& item,
ReferrerChain* out_referrer_chain) { ReferrerChain* out_referrer_chain) {
...@@ -74,6 +75,26 @@ bool MatchesEnterpriseWhitelist(const Profile* profile, ...@@ -74,6 +75,26 @@ bool MatchesEnterpriseWhitelist(const Profile* profile,
return false; return false;
} }
int GetDownloadAttributionUserGestureLimit(const download::DownloadItem& item) {
content::WebContents* web_contents =
content::DownloadItemUtils::GetWebContents(
const_cast<download::DownloadItem*>(&item));
if (!web_contents)
return kDownloadAttributionUserGestureLimit;
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
if (!profile)
return kDownloadAttributionUserGestureLimit;
const PrefService* prefs = profile->GetPrefs();
if (!prefs)
return kDownloadAttributionUserGestureLimit;
if (!IsExtendedReportingEnabled(*prefs))
return kDownloadAttributionUserGestureLimit;
return kDownloadAttributionUserGestureLimitForExtendedReporting;
}
} // namespace } // namespace
const void* const DownloadProtectionService::kDownloadPingTokenKey = const void* const DownloadProtectionService::kDownloadPingTokenKey =
...@@ -426,8 +447,8 @@ DownloadProtectionService::IdentifyReferrerChain( ...@@ -426,8 +447,8 @@ DownloadProtectionService::IdentifyReferrerChain(
// We look for the referrer chain that leads to the download url first. // We look for the referrer chain that leads to the download url first.
SafeBrowsingNavigationObserverManager::AttributionResult result = SafeBrowsingNavigationObserverManager::AttributionResult result =
navigation_observer_manager_->IdentifyReferrerChainByEventURL( navigation_observer_manager_->IdentifyReferrerChainByEventURL(
item.GetURL(), download_tab_id, kDownloadAttributionUserGestureLimit, item.GetURL(), download_tab_id,
referrer_chain.get()); GetDownloadAttributionUserGestureLimit(item), referrer_chain.get());
// If no navigation event is found, this download is not triggered by regular // If no navigation event is found, this download is not triggered by regular
// navigation (e.g. html5 file apis, etc). We look for the referrer chain // navigation (e.g. html5 file apis, etc). We look for the referrer chain
...@@ -437,7 +458,7 @@ DownloadProtectionService::IdentifyReferrerChain( ...@@ -437,7 +458,7 @@ DownloadProtectionService::IdentifyReferrerChain(
web_contents && web_contents->GetLastCommittedURL().is_valid()) { web_contents && web_contents->GetLastCommittedURL().is_valid()) {
AddEventUrlToReferrerChain(item, referrer_chain.get()); AddEventUrlToReferrerChain(item, referrer_chain.get());
result = navigation_observer_manager_->IdentifyReferrerChainByWebContents( result = navigation_observer_manager_->IdentifyReferrerChainByWebContents(
web_contents, kDownloadAttributionUserGestureLimit, web_contents, GetDownloadAttributionUserGestureLimit(item),
referrer_chain.get()); referrer_chain.get());
} }
......
...@@ -194,12 +194,14 @@ class DownloadProtectionService { ...@@ -194,12 +194,14 @@ class DownloadProtectionService {
PPAPIDownloadRequest_InvalidResponse); PPAPIDownloadRequest_InvalidResponse);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
PPAPIDownloadRequest_Timeout); PPAPIDownloadRequest_Timeout);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
VerifyReferrerChainWithEmptyNavigationHistory);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceFlagTest, FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceFlagTest,
CheckClientDownloadOverridenByFlag); CheckClientDownloadOverridenByFlag);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
VerifyMaybeSendDangerousDownloadOpenedReport); VerifyMaybeSendDangerousDownloadOpenedReport);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
VerifyReferrerChainWithEmptyNavigationHistory);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
VerifyReferrerChainLengthForExtendedReporting);
static const void* const kDownloadPingTokenKey; static const void* const kDownloadPingTokenKey;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
#include "chrome/browser/safe_browsing/download_protection/ppapi_download_request.h" #include "chrome/browser/safe_browsing/download_protection/ppapi_download_request.h"
#include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h"
#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/safe_browsing/test_extension_event_observer.h" #include "chrome/browser/safe_browsing/test_extension_event_observer.h"
#include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
...@@ -45,6 +46,7 @@ ...@@ -45,6 +46,7 @@
#include "chrome/common/safe_browsing/binary_feature_extractor.h" #include "chrome/common/safe_browsing/binary_feature_extractor.h"
#include "chrome/common/safe_browsing/file_type_policies_test_util.h" #include "chrome/common/safe_browsing/file_type_policies_test_util.h"
#include "chrome/common/safe_browsing/mock_binary_feature_extractor.h" #include "chrome/common/safe_browsing/mock_binary_feature_extractor.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "components/download/public/common/download_danger_type.h" #include "components/download/public/common/download_danger_type.h"
...@@ -61,6 +63,7 @@ ...@@ -61,6 +63,7 @@
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/download_item_utils.h" #include "content/public/browser/download_item_utils.h"
#include "content/public/browser/page_navigator.h" #include "content/public/browser/page_navigator.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h" #include "content/public/test/web_contents_tester.h"
...@@ -78,6 +81,9 @@ ...@@ -78,6 +81,9 @@
#include "third_party/zlib/google/zip.h" #include "third_party/zlib/google/zip.h"
#include "url/gurl.h" #include "url/gurl.h"
using base::RunLoop;
using content::BrowserThread;
using ::testing::_;
using ::testing::Assign; using ::testing::Assign;
using ::testing::ContainerEq; using ::testing::ContainerEq;
using ::testing::DoAll; using ::testing::DoAll;
...@@ -89,10 +95,8 @@ using ::testing::NotNull; ...@@ -89,10 +95,8 @@ using ::testing::NotNull;
using ::testing::Return; using ::testing::Return;
using ::testing::ReturnRef; using ::testing::ReturnRef;
using ::testing::SaveArg; using ::testing::SaveArg;
using ::testing::SizeIs;
using ::testing::StrictMock; using ::testing::StrictMock;
using ::testing::_;
using base::RunLoop;
using content::BrowserThread;
namespace OnDangerousDownloadOpened = namespace OnDangerousDownloadOpened =
extensions::api::safe_browsing_private::OnDangerousDownloadOpened; extensions::api::safe_browsing_private::OnDangerousDownloadOpened;
...@@ -205,22 +209,26 @@ ACTION_P(CheckDownloadUrlDone, threat_type) { ...@@ -205,22 +209,26 @@ ACTION_P(CheckDownloadUrlDone, threat_type) {
base::Unretained(arg1), arg0, threat_type)); base::Unretained(arg1), arg0, threat_type));
} }
class DownloadProtectionServiceTest : public testing::Test { class DownloadProtectionServiceTest : public ChromeRenderViewHostTestHarness {
protected: protected:
DownloadProtectionServiceTest() DownloadProtectionServiceTest() {}
: test_browser_thread_bundle_(
content::TestBrowserThreadBundle::IO_MAINLOOP) {}
void SetUp() override { void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
system_request_context_getter_ = system_request_context_getter_ =
base::MakeRefCounted<net::TestURLRequestContextGetter>( base::MakeRefCounted<net::TestURLRequestContextGetter>(
base::CreateSingleThreadTaskRunnerWithTraits( base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::IO})); {content::BrowserThread::IO}));
TestingBrowserProcess::GetGlobal()->SetSystemRequestContext( TestingBrowserProcess::GetGlobal()->SetSystemRequestContext(
system_request_context_getter_.get()); system_request_context_getter_.get());
in_process_utility_thread_helper_ =
std::make_unique<content::InProcessUtilityThreadHelper>();
// Start real threads for the IO and File threads so that the DCHECKs // Start real threads for the IO and File threads so that the DCHECKs
// to test that we're on the correct thread work. // to test that we're on the correct thread work.
sb_service_ = new StrictMock<FakeSafeBrowsingService>(); sb_service_ = new StrictMock<FakeSafeBrowsingService>();
sb_service_->Initialize(); sb_service_->Initialize();
TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(
sb_service_.get());
binary_feature_extractor_ = new StrictMock<MockBinaryFeatureExtractor>(); binary_feature_extractor_ = new StrictMock<MockBinaryFeatureExtractor>();
ON_CALL(*binary_feature_extractor_, ExtractImageFeatures(_, _, _, _)) ON_CALL(*binary_feature_extractor_, ExtractImageFeatures(_, _, _, _))
.WillByDefault(Return(true)); .WillByDefault(Return(true));
...@@ -246,11 +254,8 @@ class DownloadProtectionServiceTest : public testing::Test { ...@@ -246,11 +254,8 @@ class DownloadProtectionServiceTest : public testing::Test {
.AppendASCII("safe_browsing") .AppendASCII("safe_browsing")
.AppendASCII("download_protection"); .AppendASCII("download_protection");
// Setup a profile ASSERT_TRUE(profile()->CreateHistoryService(true /* delete_file */,
ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); false /* no_db */));
profile_.reset(new TestingProfile(profile_dir_.GetPath()));
ASSERT_TRUE(profile_->CreateHistoryService(true /* delete_file */,
false /* no_db */));
// Setup a directory to place test files in. // Setup a directory to place test files in.
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
...@@ -259,12 +264,9 @@ class DownloadProtectionServiceTest : public testing::Test { ...@@ -259,12 +264,9 @@ class DownloadProtectionServiceTest : public testing::Test {
SetBinarySamplingProbability(0.0); SetBinarySamplingProbability(0.0);
// |test_event_router_| is owned by KeyedServiceFactory. // |test_event_router_| is owned by KeyedServiceFactory.
test_event_router_ = test_event_router_ = extensions::CreateAndUseTestEventRouter(profile());
extensions::CreateAndUseTestEventRouter(profile_.get());
extensions::SafeBrowsingPrivateEventRouterFactory::GetInstance() extensions::SafeBrowsingPrivateEventRouterFactory::GetInstance()
->SetTestingFactory( ->SetTestingFactory(profile(), BuildSafeBrowsingPrivateEventRouter);
profile_.get(),
base::BindRepeating(&BuildSafeBrowsingPrivateEventRouter));
} }
void TearDown() override { void TearDown() override {
...@@ -276,7 +278,11 @@ class DownloadProtectionServiceTest : public testing::Test { ...@@ -276,7 +278,11 @@ class DownloadProtectionServiceTest : public testing::Test {
FlushThreadMessageLoops(); FlushThreadMessageLoops();
sb_service_ = NULL; sb_service_ = NULL;
TestingBrowserProcess::GetGlobal()->SetSystemRequestContext(nullptr); TestingBrowserProcess::GetGlobal()->SetSystemRequestContext(nullptr);
TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(nullptr);
system_request_context_getter_ = nullptr; system_request_context_getter_ = nullptr;
in_process_utility_thread_helper_ = nullptr;
ChromeRenderViewHostTestHarness::TearDown();
} }
void SetWhitelistedDownloadSampleRate(double target_rate) { void SetWhitelistedDownloadSampleRate(double target_rate) {
...@@ -436,11 +442,28 @@ class DownloadProtectionServiceTest : public testing::Test { ...@@ -436,11 +442,28 @@ class DownloadProtectionServiceTest : public testing::Test {
} }
void AddDomainToEnterpriseWhitelist(const std::string& domain) { void AddDomainToEnterpriseWhitelist(const std::string& domain) {
ListPrefUpdate update(profile_->GetPrefs(), ListPrefUpdate update(profile()->GetPrefs(),
prefs::kSafeBrowsingWhitelistDomains); prefs::kSafeBrowsingWhitelistDomains);
update.Get()->AppendString(domain); update.Get()->AppendString(domain);
} }
// Helper function to simulate a user gesture, then a link click.
// The usual NavigateAndCommit is unsuitable because it creates
// browser-initiated navigations, causing us to drop the referrer.
// TODO(drubery): This function could be eliminated if we dropped referrer
// depending on PageTransition. This could help eliminate edge cases in
// browser/renderer navigations.
void SimulateLinkClick(const GURL& url) {
content::WebContentsTester::For(web_contents())
->TestDidReceiveInputEvent(blink::WebInputEvent::kMouseDown);
std::unique_ptr<content::NavigationSimulator> navigation =
content::NavigationSimulator::CreateRendererInitiated(
url, web_contents()->GetMainFrame());
navigation->SetTransition(ui::PAGE_TRANSITION_LINK);
navigation->Commit();
}
private: private:
// Helper functions for FlushThreadMessageLoops. // Helper functions for FlushThreadMessageLoops.
void RunAllPendingAndQuitUI(const base::Closure& quit_closure) { void RunAllPendingAndQuitUI(const base::Closure& quit_closure) {
...@@ -507,7 +530,7 @@ class DownloadProtectionServiceTest : public testing::Test { ...@@ -507,7 +530,7 @@ class DownloadProtectionServiceTest : public testing::Test {
} }
void SetExtendedReportingPreference(bool is_extended_reporting) { void SetExtendedReportingPreference(bool is_extended_reporting) {
SetExtendedReportingPref(profile_->GetPrefs(), is_extended_reporting); SetExtendedReportingPref(profile()->GetPrefs(), is_extended_reporting);
} }
// Verify that corrupted ZIP/DMGs do send a ping. // Verify that corrupted ZIP/DMGs do send a ping.
...@@ -523,14 +546,12 @@ class DownloadProtectionServiceTest : public testing::Test { ...@@ -523,14 +546,12 @@ class DownloadProtectionServiceTest : public testing::Test {
DownloadProtectionService* download_service_; DownloadProtectionService* download_service_;
DownloadCheckResult result_; DownloadCheckResult result_;
bool has_result_; bool has_result_;
content::TestBrowserThreadBundle test_browser_thread_bundle_; std::unique_ptr<content::InProcessUtilityThreadHelper>
content::InProcessUtilityThreadHelper in_process_utility_thread_helper_; in_process_utility_thread_helper_;
base::FilePath testdata_path_; base::FilePath testdata_path_;
ClientDownloadRequestSubscription client_download_request_subscription_; ClientDownloadRequestSubscription client_download_request_subscription_;
PPAPIDownloadRequestSubscription ppapi_download_request_subscription_; PPAPIDownloadRequestSubscription ppapi_download_request_subscription_;
std::unique_ptr<ClientDownloadRequest> last_client_download_request_; std::unique_ptr<ClientDownloadRequest> last_client_download_request_;
base::ScopedTempDir profile_dir_;
std::unique_ptr<TestingProfile> profile_;
// The following 5 fields are used by PrepareBasicDownloadItem() function to // The following 5 fields are used by PrepareBasicDownloadItem() function to
// store attributes of the last download item. They can be modified // store attributes of the last download item. They can be modified
// afterwards and the *item will return the new values. // afterwards and the *item will return the new values.
...@@ -767,7 +788,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -767,7 +788,7 @@ TEST_F(DownloadProtectionServiceTest,
// ClientDownloadRequest should NOT be sent. // ClientDownloadRequest should NOT be sent.
SetExtendedReportingPreference(true); SetExtendedReportingPreference(true);
content::DownloadItemUtils::AttachInfo( content::DownloadItemUtils::AttachInfo(
&item, profile_->GetOffTheRecordProfile(), nullptr); &item, profile()->GetOffTheRecordProfile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -781,7 +802,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -781,7 +802,7 @@ TEST_F(DownloadProtectionServiceTest,
// ClientDownloadRequest should NOT be sent. // ClientDownloadRequest should NOT be sent.
SetExtendedReportingPreference(false); SetExtendedReportingPreference(false);
content::DownloadItemUtils::AttachInfo( content::DownloadItemUtils::AttachInfo(
&item, profile_->GetOffTheRecordProfile(), nullptr); &item, profile()->GetOffTheRecordProfile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -793,7 +814,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -793,7 +814,7 @@ TEST_F(DownloadProtectionServiceTest,
{ {
// Case (3): !is_extended_reporting && !is_incognito. // Case (3): !is_extended_reporting && !is_incognito.
// ClientDownloadRequest should NOT be sent. // ClientDownloadRequest should NOT be sent.
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -807,7 +828,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -807,7 +828,7 @@ TEST_F(DownloadProtectionServiceTest,
// Download matches URL whitelist. // Download matches URL whitelist.
// ClientDownloadRequest should be sent. // ClientDownloadRequest should be sent.
SetExtendedReportingPreference(true); SetExtendedReportingPreference(true);
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -836,7 +857,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -836,7 +857,7 @@ TEST_F(DownloadProtectionServiceTest,
// Case (5): is_extended_reporting && !is_incognito && // Case (5): is_extended_reporting && !is_incognito &&
// Download matches certificate whitelist. // Download matches certificate whitelist.
// ClientDownloadRequest should be sent. // ClientDownloadRequest should be sent.
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
EXPECT_CALL( EXPECT_CALL(
*sb_service_->mock_database_manager(), *sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe"))) MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe")))
...@@ -856,7 +877,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -856,7 +877,7 @@ TEST_F(DownloadProtectionServiceTest,
// Case (6): is_extended_reporting && !is_incognito && // Case (6): is_extended_reporting && !is_incognito &&
// Download matches both URL and certificate whitelists. // Download matches both URL and certificate whitelists.
// ClientDownloadRequest should be sent. // ClientDownloadRequest should be sent.
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
EXPECT_CALL( EXPECT_CALL(
*sb_service_->mock_database_manager(), *sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe"))) MatchDownloadWhitelistUrl(GURL("http://www.whitelist.com/a.exe")))
...@@ -906,7 +927,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) { ...@@ -906,7 +927,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) {
// ClientDownloadRequest should NOT be sent. // ClientDownloadRequest should NOT be sent.
SetExtendedReportingPreference(true); SetExtendedReportingPreference(true);
content::DownloadItemUtils::AttachInfo( content::DownloadItemUtils::AttachInfo(
&item, profile_->GetOffTheRecordProfile(), nullptr); &item, profile()->GetOffTheRecordProfile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -918,7 +939,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) { ...@@ -918,7 +939,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) {
{ {
// Case (2): is_extended_reporting && !is_incognito. // Case (2): is_extended_reporting && !is_incognito.
// A "light" ClientDownloadRequest should be sent. // A "light" ClientDownloadRequest should be sent.
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -944,7 +965,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) { ...@@ -944,7 +965,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) {
// ClientDownloadRequest should NOT be sent. // ClientDownloadRequest should NOT be sent.
SetExtendedReportingPreference(false); SetExtendedReportingPreference(false);
content::DownloadItemUtils::AttachInfo( content::DownloadItemUtils::AttachInfo(
&item, profile_->GetOffTheRecordProfile(), nullptr); &item, profile()->GetOffTheRecordProfile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -956,7 +977,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) { ...@@ -956,7 +977,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSampledFile) {
{ {
// Case (4): !is_extended_reporting && !is_incognito. // Case (4): !is_extended_reporting && !is_incognito.
// ClientDownloadRequest should NOT be sent. // ClientDownloadRequest should NOT be sent.
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckClientDownload( download_service_->CheckClientDownload(
&item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, &item, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
...@@ -1849,7 +1870,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -1849,7 +1870,7 @@ TEST_F(DownloadProtectionServiceTest,
EXPECT_CALL(item, GetTabReferrerUrl()) EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(tab_referrer)); .WillRepeatedly(ReturnRef(tab_referrer));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address)); EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
EXPECT_CALL(*sb_service_->mock_database_manager(), EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_)) MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false)); .WillRepeatedly(Return(false));
...@@ -1935,7 +1956,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -1935,7 +1956,7 @@ TEST_F(DownloadProtectionServiceTest,
redirects.push_back(GURL("http://tab.com/ref1")); redirects.push_back(GURL("http://tab.com/ref1"));
redirects.push_back(GURL("http://tab.com/ref2")); redirects.push_back(GURL("http://tab.com/ref2"));
redirects.push_back(tab_url); redirects.push_back(tab_url);
HistoryServiceFactory::GetForProfile(profile_.get(), HistoryServiceFactory::GetForProfile(profile(),
ServiceAccessType::EXPLICIT_ACCESS) ServiceAccessType::EXPLICIT_ACCESS)
->AddPage(tab_url, base::Time::Now(), ->AddPage(tab_url, base::Time::Now(),
reinterpret_cast<history::ContextID>(1), 0, GURL(), redirects, reinterpret_cast<history::ContextID>(1), 0, GURL(), redirects,
...@@ -2066,10 +2087,8 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -2066,10 +2087,8 @@ TEST_F(DownloadProtectionServiceTest,
FILE_PATH_LITERAL("a.tmp"), // tmp_path FILE_PATH_LITERAL("a.tmp"), // tmp_path
FILE_PATH_LITERAL("a.exe")); // final_path FILE_PATH_LITERAL("a.exe")); // final_path
std::unique_ptr<content::WebContents> web_contents( std::unique_ptr<content::WebContents> web_contents(
content::WebContentsTester::CreateTestWebContents(profile_.get(), content::WebContentsTester::CreateTestWebContents(profile(), nullptr));
nullptr)); content::DownloadItemUtils::AttachInfo(&item, profile(), web_contents.get());
content::DownloadItemUtils::AttachInfo(&item, profile_.get(),
web_contents.get());
EXPECT_CALL(*sb_service_->mock_database_manager(), CheckDownloadUrl(_, _)) EXPECT_CALL(*sb_service_->mock_database_manager(), CheckDownloadUrl(_, _))
.Times(0); .Times(0);
RunLoop run_loop; RunLoop run_loop;
...@@ -2088,8 +2107,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -2088,8 +2107,7 @@ TEST_F(DownloadProtectionServiceTest,
"http://referrer.com", // referrer "http://referrer.com", // referrer
FILE_PATH_LITERAL("a.tmp"), // tmp_path FILE_PATH_LITERAL("a.tmp"), // tmp_path
FILE_PATH_LITERAL("a.exe")); // final_path FILE_PATH_LITERAL("a.exe")); // final_path
content::DownloadItemUtils::AttachInfo(&item2, profile_.get(), content::DownloadItemUtils::AttachInfo(&item2, profile(), web_contents.get());
web_contents.get());
EXPECT_CALL(*sb_service_->mock_database_manager(), CheckDownloadUrl(_, _)) EXPECT_CALL(*sb_service_->mock_database_manager(), CheckDownloadUrl(_, _))
.Times(0); .Times(0);
RunLoop run_loop2; RunLoop run_loop2;
...@@ -2332,7 +2350,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_Unsupported) { ...@@ -2332,7 +2350,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_Unsupported) {
FILE_PATH_LITERAL(".tmp"), FILE_PATH_LITERAL(".asdfasdf")}; FILE_PATH_LITERAL(".tmp"), FILE_PATH_LITERAL(".asdfasdf")};
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, GURL("http://example.com/foo"), GURL(), nullptr, default_file_path,
alternate_extensions, profile_.get(), alternate_extensions, profile(),
base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
base::Unretained(this))); base::Unretained(this)));
ASSERT_TRUE(IsResult(DownloadCheckResult::SAFE)); ASSERT_TRUE(IsResult(DownloadCheckResult::SAFE));
...@@ -2366,7 +2384,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_SupportedDefault) { ...@@ -2366,7 +2384,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_SupportedDefault) {
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, GURL("http://example.com/foo"), GURL(), nullptr, default_file_path,
alternate_extensions, profile_.get(), alternate_extensions, profile(),
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this), run_loop.QuitClosure())); base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run(); run_loop.Run();
...@@ -2389,7 +2407,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_SupportedAlternate) { ...@@ -2389,7 +2407,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_SupportedAlternate) {
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, GURL("http://example.com/foo"), GURL(), nullptr, default_file_path,
alternate_extensions, profile_.get(), alternate_extensions, profile(),
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this), run_loop.QuitClosure())); base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run(); run_loop.Run();
...@@ -2409,7 +2427,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_WhitelistedURL) { ...@@ -2409,7 +2427,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_WhitelistedURL) {
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, GURL("http://example.com/foo"), GURL(), nullptr, default_file_path,
alternate_extensions, profile_.get(), alternate_extensions, profile(),
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this), run_loop.QuitClosure())); base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run(); run_loop.Run();
...@@ -2428,7 +2446,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_FetchFailed) { ...@@ -2428,7 +2446,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_FetchFailed) {
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, GURL("http://example.com/foo"), GURL(), nullptr, default_file_path,
alternate_extensions, profile_.get(), alternate_extensions, profile(),
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this), run_loop.QuitClosure())); base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run(); run_loop.Run();
...@@ -2447,7 +2465,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_InvalidResponse) { ...@@ -2447,7 +2465,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_InvalidResponse) {
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, GURL("http://example.com/foo"), GURL(), nullptr, default_file_path,
alternate_extensions, profile_.get(), alternate_extensions, profile(),
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this), run_loop.QuitClosure())); base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run(); run_loop.Run();
...@@ -2467,7 +2485,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_Timeout) { ...@@ -2467,7 +2485,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_Timeout) {
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), nullptr, default_file_path, GURL("http://example.com/foo"), GURL(), nullptr, default_file_path,
alternate_extensions, profile_.get(), alternate_extensions, profile(),
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this), run_loop.QuitClosure())); base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run(); run_loop.Run();
...@@ -2497,7 +2515,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_Payload) { ...@@ -2497,7 +2515,7 @@ TEST_F(DownloadProtectionServiceTest, PPAPIDownloadRequest_Payload) {
RunLoop run_loop; RunLoop run_loop;
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
kRequestorUrl, GURL(), nullptr, default_file_path, alternate_extensions, kRequestorUrl, GURL(), nullptr, default_file_path, alternate_extensions,
profile_.get(), profile(),
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback, base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this), run_loop.QuitClosure())); base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run(); run_loop.Run();
...@@ -2520,15 +2538,14 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -2520,15 +2538,14 @@ TEST_F(DownloadProtectionServiceTest,
PPAPIDownloadRequest_WhitelistedByPolicy) { PPAPIDownloadRequest_WhitelistedByPolicy) {
AddDomainToEnterpriseWhitelist("example.com"); AddDomainToEnterpriseWhitelist("example.com");
std::unique_ptr<content::WebContents> web_contents( std::unique_ptr<content::WebContents> web_contents(
content::WebContentsTester::CreateTestWebContents(profile_.get(), content::WebContentsTester::CreateTestWebContents(profile(), nullptr));
nullptr));
base::FilePath default_file_path(FILE_PATH_LITERAL("/foo/bar/test.txt")); base::FilePath default_file_path(FILE_PATH_LITERAL("/foo/bar/test.txt"));
std::vector<base::FilePath::StringType> alternate_extensions{ std::vector<base::FilePath::StringType> alternate_extensions{
FILE_PATH_LITERAL(".tmp"), FILE_PATH_LITERAL(".asdfasdf")}; FILE_PATH_LITERAL(".tmp"), FILE_PATH_LITERAL(".asdfasdf")};
download_service_->CheckPPAPIDownloadRequest( download_service_->CheckPPAPIDownloadRequest(
GURL("http://example.com/foo"), GURL(), web_contents.get(), GURL("http://example.com/foo"), GURL(), web_contents.get(),
default_file_path, alternate_extensions, profile_.get(), default_file_path, alternate_extensions, profile(),
base::BindRepeating(&DownloadProtectionServiceTest::SyncCheckDoneCallback, base::BindRepeating(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
base::Unretained(this))); base::Unretained(this)));
ASSERT_TRUE(IsResult(DownloadCheckResult::WHITELISTED_BY_POLICY)); ASSERT_TRUE(IsResult(DownloadCheckResult::WHITELISTED_BY_POLICY));
...@@ -2542,7 +2559,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -2542,7 +2559,7 @@ TEST_F(DownloadProtectionServiceTest,
"http://www.google.com/", // referrer "http://www.google.com/", // referrer
FILE_PATH_LITERAL("a.tmp"), // tmp_path FILE_PATH_LITERAL("a.tmp"), // tmp_path
FILE_PATH_LITERAL("a.exe")); // final_path FILE_PATH_LITERAL("a.exe")); // final_path
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
ASSERT_EQ(0, sb_service_->download_report_count()); ASSERT_EQ(0, sb_service_->download_report_count());
// No report sent if download item without token field. // No report sent if download item without token field.
...@@ -2552,12 +2569,12 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -2552,12 +2569,12 @@ TEST_F(DownloadProtectionServiceTest,
// No report sent if user is in incognito mode. // No report sent if user is in incognito mode.
DownloadProtectionService::SetDownloadPingToken(&item, "token"); DownloadProtectionService::SetDownloadPingToken(&item, "token");
content::DownloadItemUtils::AttachInfo( content::DownloadItemUtils::AttachInfo(
&item, profile_->GetOffTheRecordProfile(), nullptr); &item, profile()->GetOffTheRecordProfile(), nullptr);
download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false); download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false);
EXPECT_EQ(0, sb_service_->download_report_count()); EXPECT_EQ(0, sb_service_->download_report_count());
// No report sent if user is not in extended reporting group. // No report sent if user is not in extended reporting group.
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
SetExtendedReportingPreference(false); SetExtendedReportingPreference(false);
download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false); download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false);
EXPECT_EQ(0, sb_service_->download_report_count()); EXPECT_EQ(0, sb_service_->download_report_count());
...@@ -2585,7 +2602,7 @@ TEST_F(DownloadProtectionServiceTest, VerifyDangerousDownloadOpenedAPICall) { ...@@ -2585,7 +2602,7 @@ TEST_F(DownloadProtectionServiceTest, VerifyDangerousDownloadOpenedAPICall) {
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(target_path)); EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(target_path));
TestExtensionEventObserver event_observer(test_event_router_); TestExtensionEventObserver event_observer(test_event_router_);
content::DownloadItemUtils::AttachInfo(&item, profile_.get(), nullptr); content::DownloadItemUtils::AttachInfo(&item, profile(), nullptr);
download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false); download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false);
ASSERT_EQ(1, test_event_router_->GetEventCount( ASSERT_EQ(1, test_event_router_->GetEventCount(
OnDangerousDownloadOpened::kEventName)); OnDangerousDownloadOpened::kEventName));
...@@ -2599,43 +2616,12 @@ TEST_F(DownloadProtectionServiceTest, VerifyDangerousDownloadOpenedAPICall) { ...@@ -2599,43 +2616,12 @@ TEST_F(DownloadProtectionServiceTest, VerifyDangerousDownloadOpenedAPICall) {
// No event is triggered if in incognito mode.. // No event is triggered if in incognito mode..
content::DownloadItemUtils::AttachInfo( content::DownloadItemUtils::AttachInfo(
&item, profile_->GetOffTheRecordProfile(), nullptr); &item, profile()->GetOffTheRecordProfile(), nullptr);
download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false); download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false);
EXPECT_EQ(1, test_event_router_->GetEventCount( EXPECT_EQ(1, test_event_router_->GetEventCount(
OnDangerousDownloadOpened::kEventName)); OnDangerousDownloadOpened::kEventName));
} }
TEST_F(DownloadProtectionServiceTest,
VerifyReferrerChainWithEmptyNavigationHistory) {
// Setup a web_contents with "http://example.com" as its last committed url.
std::unique_ptr<content::WebContents> web_contents(
content::WebContentsTester::CreateTestWebContents(profile_.get(),
nullptr));
content::WebContentsTester* web_contents_tester =
content::WebContentsTester::For(web_contents.get());
web_contents_tester->SetLastCommittedURL(GURL("http://example.com"));
NiceMockDownloadItem item;
PrepareBasicDownloadItem(
&item, {"http://referrer.com", "http://www.evil.com/a.exe"}, // url_chain
"http://example.com/", // referrer
FILE_PATH_LITERAL("a.tmp"), // tmp_path
FILE_PATH_LITERAL("a.exe")); // final_path
content::DownloadItemUtils::AttachInfo(&item, nullptr, web_contents.get());
std::unique_ptr<ReferrerChainData> referrer_chain_data =
download_service_->IdentifyReferrerChain(item);
ReferrerChain* referrer_chain = referrer_chain_data->GetReferrerChain();
ASSERT_EQ(1u, referrer_chain_data->referrer_chain_length());
EXPECT_EQ(item.GetUrlChain().back(), referrer_chain->Get(0).url());
EXPECT_EQ(web_contents->GetLastCommittedURL().spec(),
referrer_chain->Get(0).referrer_url());
EXPECT_EQ(ReferrerChainEntry::EVENT_URL, referrer_chain->Get(0).type());
EXPECT_EQ(static_cast<int>(item.GetUrlChain().size()),
referrer_chain->Get(0).server_redirect_chain_size());
EXPECT_FALSE(referrer_chain->Get(0).is_retargeting());
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedByPolicy) { TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedByPolicy) {
NiceMockDownloadItem item; NiceMockDownloadItem item;
PrepareBasicDownloadItem(&item, {"http://www.evil.com/a.exe"}, // url_chain PrepareBasicDownloadItem(&item, {"http://www.evil.com/a.exe"}, // url_chain
...@@ -2669,7 +2655,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedByPolicy) { ...@@ -2669,7 +2655,7 @@ TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedByPolicy) {
TEST_F(DownloadProtectionServiceTest, CheckOffTheRecordDoesNotSendFeedback) { TEST_F(DownloadProtectionServiceTest, CheckOffTheRecordDoesNotSendFeedback) {
NiceMockDownloadItem item; NiceMockDownloadItem item;
EXPECT_FALSE(download_service_->MaybeBeginFeedbackForDownload( EXPECT_FALSE(download_service_->MaybeBeginFeedbackForDownload(
profile_->GetOffTheRecordProfile(), &item, DownloadCommands::KEEP)); profile()->GetOffTheRecordProfile(), &item, DownloadCommands::KEEP));
} }
TEST_F(DownloadProtectionServiceTest, TEST_F(DownloadProtectionServiceTest,
...@@ -2678,7 +2664,7 @@ TEST_F(DownloadProtectionServiceTest, ...@@ -2678,7 +2664,7 @@ TEST_F(DownloadProtectionServiceTest,
NiceMockDownloadItem item; NiceMockDownloadItem item;
EXPECT_FALSE(download_service_->MaybeBeginFeedbackForDownload( EXPECT_FALSE(download_service_->MaybeBeginFeedbackForDownload(
profile_.get(), &item, DownloadCommands::KEEP)); profile(), &item, DownloadCommands::KEEP));
} }
// ------------ class DownloadProtectionServiceFlagTest ---------------- // ------------ class DownloadProtectionServiceFlagTest ----------------
...@@ -2763,4 +2749,61 @@ TEST_F(DownloadProtectionServiceFlagTest, ...@@ -2763,4 +2749,61 @@ TEST_F(DownloadProtectionServiceFlagTest,
EXPECT_TRUE(IsResult(DownloadCheckResult::DANGEROUS)); EXPECT_TRUE(IsResult(DownloadCheckResult::DANGEROUS));
} }
TEST_F(DownloadProtectionServiceTest,
VerifyReferrerChainWithEmptyNavigationHistory) {
// Setup a web_contents with "http://example.com" as its last committed url.
NavigateAndCommit(GURL("http://example.com"));
NiceMockDownloadItem item;
std::vector<GURL> url_chain = {GURL("http://example.com/referrer"),
GURL("http://example.com/evil.exe")};
EXPECT_CALL(item, GetURL()).WillRepeatedly(ReturnRef(url_chain.back()));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
content::DownloadItemUtils::AttachInfo(&item, nullptr, web_contents());
std::unique_ptr<ReferrerChainData> referrer_chain_data =
download_service_->IdentifyReferrerChain(item);
ReferrerChain* referrer_chain = referrer_chain_data->GetReferrerChain();
ASSERT_EQ(1u, referrer_chain_data->referrer_chain_length());
EXPECT_EQ(item.GetUrlChain().back(), referrer_chain->Get(0).url());
EXPECT_EQ(web_contents()->GetLastCommittedURL().spec(),
referrer_chain->Get(0).referrer_url());
EXPECT_EQ(ReferrerChainEntry::EVENT_URL, referrer_chain->Get(0).type());
EXPECT_EQ(static_cast<int>(item.GetUrlChain().size()),
referrer_chain->Get(0).server_redirect_chain_size());
EXPECT_FALSE(referrer_chain->Get(0).is_retargeting());
}
TEST_F(DownloadProtectionServiceTest,
VerifyReferrerChainLengthForExtendedReporting) {
SafeBrowsingNavigationObserver::MaybeCreateForWebContents(web_contents());
// Simulate 6 user interactions
SimulateLinkClick(GURL("http://example.com/0"));
SimulateLinkClick(GURL("http://example.com/1"));
SimulateLinkClick(GURL("http://example.com/2"));
SimulateLinkClick(GURL("http://example.com/3"));
SimulateLinkClick(GURL("http://example.com/4"));
SimulateLinkClick(GURL("http://example.com/5"));
SimulateLinkClick(GURL("http://example.com/evil.exe"));
NiceMockDownloadItem item;
std::vector<GURL> url_chain = {GURL("http://example.com/evil.exe")};
EXPECT_CALL(item, GetURL()).WillRepeatedly(ReturnRef(url_chain.back()));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
content::DownloadItemUtils::AttachInfo(&item, nullptr, web_contents());
SetExtendedReportingPref(profile()->GetPrefs(), true);
std::unique_ptr<ReferrerChainData> referrer_chain_data =
download_service_->IdentifyReferrerChain(item);
// 6 entries means 5 interactions between entries.
EXPECT_EQ(referrer_chain_data->referrer_chain_length(), 6u);
SetExtendedReportingPref(profile()->GetPrefs(), false);
referrer_chain_data = download_service_->IdentifyReferrerChain(item);
// 3 entries means 2 interactions between entries.
EXPECT_EQ(referrer_chain_data->referrer_chain_length(), 3u);
}
} // namespace safe_browsing } // namespace safe_browsing
...@@ -49,7 +49,7 @@ bool IsEventExpired(const base::Time& event_time, double ttl_in_second) { ...@@ -49,7 +49,7 @@ bool IsEventExpired(const base::Time& event_time, double ttl_in_second) {
// Helper function to determine if the URL type should be LANDING_REFERRER or // Helper function to determine if the URL type should be LANDING_REFERRER or
// LANDING_PAGE, and modify AttributionResult accordingly. // LANDING_PAGE, and modify AttributionResult accordingly.
ReferrerChainEntry::URLType GetURLTypeAndAdjustAttributionResult( ReferrerChainEntry::URLType GetURLTypeAndAdjustAttributionResult(
bool at_user_gesture_limit, size_t user_gesture_count,
SafeBrowsingNavigationObserverManager::AttributionResult* out_result) { SafeBrowsingNavigationObserverManager::AttributionResult* out_result) {
// Landing page refers to the page user directly interacts with to trigger // Landing page refers to the page user directly interacts with to trigger
// this event (e.g. clicking on download button). Landing referrer page is the // this event (e.g. clicking on download button). Landing referrer page is the
...@@ -57,13 +57,19 @@ ReferrerChainEntry::URLType GetURLTypeAndAdjustAttributionResult( ...@@ -57,13 +57,19 @@ ReferrerChainEntry::URLType GetURLTypeAndAdjustAttributionResult(
// Since we are tracing navigations backwards, if we've reached // Since we are tracing navigations backwards, if we've reached
// user gesture limit before this navigation event, this is a navigation // user gesture limit before this navigation event, this is a navigation
// leading to the landing referrer page, otherwise it leads to landing page. // leading to the landing referrer page, otherwise it leads to landing page.
if (at_user_gesture_limit) { if (user_gesture_count == 0) {
*out_result = SafeBrowsingNavigationObserverManager::SUCCESS;
return ReferrerChainEntry::EVENT_URL;
} else if (user_gesture_count == 2) {
*out_result = *out_result =
SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER; SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER;
return ReferrerChainEntry::LANDING_REFERRER; return ReferrerChainEntry::LANDING_REFERRER;
} else { } else if (user_gesture_count == 1) {
*out_result = SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE; *out_result = SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE;
return ReferrerChainEntry::LANDING_PAGE; return ReferrerChainEntry::LANDING_PAGE;
} else {
*out_result = SafeBrowsingNavigationObserverManager::SUCCESS_REFERRER;
return ReferrerChainEntry::REFERRER;
} }
} }
...@@ -424,8 +430,7 @@ SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByHostingPage( ...@@ -424,8 +430,7 @@ SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByHostingPage(
user_gesture_count = 1; user_gesture_count = 1;
AddToReferrerChain( AddToReferrerChain(
out_referrer_chain, nav_event, initiating_main_frame_url, out_referrer_chain, nav_event, initiating_main_frame_url,
GetURLTypeAndAdjustAttributionResult( GetURLTypeAndAdjustAttributionResult(user_gesture_count, &result));
user_gesture_count == user_gesture_count_limit, &result));
} else { } else {
AddToReferrerChain(out_referrer_chain, nav_event, initiating_main_frame_url, AddToReferrerChain(out_referrer_chain, nav_event, initiating_main_frame_url,
ReferrerChainEntry::CLIENT_REDIRECT); ReferrerChainEntry::CLIENT_REDIRECT);
...@@ -667,11 +672,10 @@ void SafeBrowsingNavigationObserverManager::GetRemainingReferrerChain( ...@@ -667,11 +672,10 @@ void SafeBrowsingNavigationObserverManager::GetRemainingReferrerChain(
if (!last_nav_event_traced) if (!last_nav_event_traced)
return; return;
AddToReferrerChain( AddToReferrerChain(out_referrer_chain, last_nav_event_traced,
out_referrer_chain, last_nav_event_traced, last_main_frame_url_traced, last_main_frame_url_traced,
GetURLTypeAndAdjustAttributionResult( GetURLTypeAndAdjustAttributionResult(
current_user_gesture_count == user_gesture_count_limit, current_user_gesture_count, out_result));
out_result));
// Stop searching if the size of out_referrer_chain already reached its // Stop searching if the size of out_referrer_chain already reached its
// limit. // limit.
if (out_referrer_chain->size() == kReferrerChainMaxLength) if (out_referrer_chain->size() == kReferrerChainMaxLength)
......
...@@ -26,6 +26,8 @@ class ReferrerChainProvider { ...@@ -26,6 +26,8 @@ class ReferrerChainProvider {
SUCCESS_LANDING_REFERRER = 3, // Successfully identified landing referrer. SUCCESS_LANDING_REFERRER = 3, // Successfully identified landing referrer.
INVALID_URL = 4, INVALID_URL = 4,
NAVIGATION_EVENT_NOT_FOUND = 5, NAVIGATION_EVENT_NOT_FOUND = 5,
SUCCESS_REFERRER = 6, // Successfully identified extra referrers beyond the
// landing referrer.
// Always at the end. // Always at the end.
ATTRIBUTION_FAILURE_TYPE_MAX ATTRIBUTION_FAILURE_TYPE_MAX
......
...@@ -660,6 +660,11 @@ message ReferrerChainEntry { ...@@ -660,6 +660,11 @@ message ReferrerChainEntry {
// chain is empty or partially missing, we will add/append recent navigation // chain is empty or partially missing, we will add/append recent navigation
// events to this list. RECENT_NAVIGATION type is set for these cases. // events to this list. RECENT_NAVIGATION type is set for these cases.
RECENT_NAVIGATION = 6; RECENT_NAVIGATION = 6;
// The REFERRER type is used for entries that recede the LANDING_REFERRER in
// the referrer chain, when more than two gestures are included in the
// referrer chain.
REFERRER = 7;
} }
enum NavigationInitiation { enum NavigationInitiation {
......
...@@ -376,6 +376,9 @@ base::Value SerializeReferrer(const ReferrerChainEntry& referrer) { ...@@ -376,6 +376,9 @@ base::Value SerializeReferrer(const ReferrerChainEntry& referrer) {
case ReferrerChainEntry::RECENT_NAVIGATION: case ReferrerChainEntry::RECENT_NAVIGATION:
url_type = "RECENT_NAVIGATION"; url_type = "RECENT_NAVIGATION";
break; break;
case ReferrerChainEntry::REFERRER:
url_type = "REFERRER";
break;
} }
referrer_dict.SetKey("type", base::Value(url_type)); referrer_dict.SetKey("type", base::Value(url_type));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment