| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h" |
| |
| #include <memory> |
| |
| #include "base/functional/callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/run_loop.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| #include "chrome/browser/download/download_core_service.h" |
| #include "chrome/browser/download/download_prefs.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h" |
| #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" |
| #include "chrome/browser/safe_browsing/test_safe_browsing_navigation_observer_manager.h" |
| #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/download/public/common/download_item.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" |
| #include "components/sessions/content/session_tab_helper.h" |
| #include "content/public/browser/browser_context.h" |
| #include "content/public/browser/download_item_utils.h" |
| #include "content/public/browser/download_manager.h" |
| #include "content/public/browser/global_routing_id.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/fenced_frame_test_util.h" |
| #include "content/public/test/prerender_test_util.h" |
| #include "content/public/test/test_navigation_observer.h" |
| #include "content/public/test/test_utils.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| #include "third_party/blink/public/common/features.h" |
| #include "url/gurl.h" |
| #include "url/url_canon.h" |
| |
| using content::DownloadManager; |
| using download::DownloadItem; |
| |
| namespace safe_browsing { |
| |
| const char kSingleFrameTestURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "navigation_observer_tests.html"; |
| const char kMultiFrameTestURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "navigation_observer_multi_frame_tests.html"; |
| const char kSubFrameTestURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "iframe.html"; |
| const char kRedirectURL[] = |
| "/safe_browsing/download_protection/navigation_observer/redirect.html"; |
| const char kEmptyURL[] = "/empty.html"; |
| const char kBasicIframeURL[] = "/iframe.html"; |
| // This is the src of the iframe in iframe.html above. |
| const char kInitialSubframeUrl[] = "/title1.html"; |
| // Please update |kShortDataURL| too if you're changing |kDownloadDataURL|. |
| const char kDownloadDataURL[] = |
| "data:application/octet-stream;base64,a2poYWxrc2hkbGtoYXNka2xoYXNsa2RoYWxra" |
| "GtoYWxza2hka2xzamFoZGxramhhc2xka2hhc2xrZGgKYXNrZGpoa2FzZGpoYWtzaGRrYXNoZGt" |
| "oYXNrZGhhc2tkaGthc2hka2Foc2RraGFrc2hka2FzaGRraGFzCmFza2pkaGFrc2hkbSxjbmtza" |
| "mFoZGtoYXNrZGhhc2tka2hrYXNkCjg3MzQ2ODEyNzQ2OGtqc2hka2FoZHNrZGhraApha3NqZGt" |
| "hc2Roa3NkaGthc2hka2FzaGtkaAohISomXkAqJl4qYWhpZGFzeWRpeWlhc1xcb1wKa2Fqc2Roa" |
| "2FzaGRrYXNoZGsKYWtzamRoc2tkaAplbmQK"; |
| // Short data url is computed by keeping the prefix of |kDownloadDataURL| up to |
| // the first ",", and appending the hash (SHA256) of entire |kDownloadDataURL|. |
| // e.g., |
| // $echo -n <kDownloadDataURL> | sha256sum | |
| // awk '{print "data:application/octet-stream;base64,"toupper($1)}' |
| const char kShortDataURL[] = |
| "data:application/octet-stream;base64,4A19A03B1EF9D2C3061C5B87BF7D0BE05998D" |
| "A5F6BA693B6759B47EEA211D246"; |
| const char kIframeDirectDownloadURL[] = |
| "/safe_browsing/download_protection/navigation_observer/iframe.html"; |
| const char kIframeRetargetingURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "iframe_retargeting.html"; |
| const char kDownloadItemURL[] = "/safe_browsing/download_protection/signed.exe"; |
| const char kRedirectToLandingURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "redirect_to_landing.html"; |
| const char kLandingURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "landing.html"; |
| const char kLandingReferrerURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "landing_referrer.html"; |
| const char kLandingReferrerURLWithQuery[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "landing_referrer.html?bar=foo"; |
| const char kPageBeforeLandingReferrerURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "page_before_landing_referrer.html"; |
| const char kCreateIframeElementURL[] = |
| "/safe_browsing/download_protection/navigation_observer/" |
| "create_iframe_element.html"; |
| |
| class DownloadItemCreatedObserver : public DownloadManager::Observer { |
| public: |
| explicit DownloadItemCreatedObserver(DownloadManager* manager) |
| : manager_(manager) { |
| manager->AddObserver(this); |
| } |
| |
| DownloadItemCreatedObserver(const DownloadItemCreatedObserver&) = delete; |
| DownloadItemCreatedObserver& operator=(const DownloadItemCreatedObserver&) = |
| delete; |
| |
| ~DownloadItemCreatedObserver() override { |
| if (manager_) |
| manager_->RemoveObserver(this); |
| } |
| |
| // Wait for the first download item created after object creation. |
| void WaitForDownloadItem( |
| std::vector<raw_ptr<DownloadItem, VectorExperimental>>* items_seen) { |
| if (!manager_) { |
| // The manager went away before we were asked to wait; return |
| // what we have, even if it's null. |
| *items_seen = items_seen_; |
| return; |
| } |
| |
| if (items_seen_.empty()) { |
| base::RunLoop run_loop; |
| quit_waiting_callback_ = run_loop.QuitClosure(); |
| run_loop.Run(); |
| quit_waiting_callback_ = base::OnceClosure(); |
| } |
| |
| *items_seen = items_seen_; |
| return; |
| } |
| |
| private: |
| // DownloadManager::Observer |
| void OnDownloadCreated(DownloadManager* manager, |
| DownloadItem* item) override { |
| DCHECK_EQ(manager, manager_); |
| items_seen_.push_back(item); |
| |
| if (!quit_waiting_callback_.is_null()) |
| std::move(quit_waiting_callback_).Run(); |
| } |
| |
| void ManagerGoingDown(DownloadManager* manager) override { |
| manager_->RemoveObserver(this); |
| manager_ = nullptr; |
| if (!quit_waiting_callback_.is_null()) |
| std::move(quit_waiting_callback_).Run(); |
| } |
| |
| base::OnceClosure quit_waiting_callback_; |
| raw_ptr<DownloadManager> manager_; |
| std::vector<raw_ptr<DownloadItem, VectorExperimental>> items_seen_; |
| }; |
| |
| class SBNavigationObserverBrowserTest : public InProcessBrowserTest { |
| public: |
| SBNavigationObserverBrowserTest() |
| : prerender_helper_( |
| base::BindRepeating(&SBNavigationObserverBrowserTest::web_contents, |
| base::Unretained(this))) {} |
| |
| void SetUp() override { |
| prerender_helper_.RegisterServerRequestMonitor(embedded_test_server()); |
| InProcessBrowserTest::SetUp(); |
| } |
| |
| void SetUpOnMainThread() override { |
| // Disable Safe Browsing service so we can directly control when |
| // SafeBrowsingNavigationObserverManager and SafeBrowsingNavigationObserver |
| // are instantiated. |
| browser()->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, |
| false); |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| host_resolver()->AddRule("*", "127.0.0.1"); |
| observer_manager_ = |
| std::make_unique<TestSafeBrowsingNavigationObserverManager>(browser()); |
| observer_manager_->ObserveContents( |
| browser()->tab_strip_model()->GetActiveWebContents()); |
| ASSERT_TRUE(InitialSetup()); |
| } |
| |
| content::WebContents* web_contents() { |
| return browser()->tab_strip_model()->GetActiveWebContents(); |
| } |
| |
| bool InitialSetup() { |
| if (!browser()) |
| return false; |
| |
| browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload, |
| false); |
| content::DownloadManager* manager = |
| browser()->profile()->GetDownloadManager(); |
| DownloadPrefs::FromDownloadManager(manager)->ResetAutoOpenByUser(); |
| |
| return true; |
| } |
| |
| void TearDownOnMainThread() override { |
| observer_manager_.reset(); |
| // Cancel unfinished download if any. |
| CancelDownloads(); |
| CHECK_EQ(DownloadCoreService::BlockingShutdownCountAllProfiles(), 0); |
| } |
| |
| // Most test cases will trigger downloads, though we don't really care if |
| // download completed or not. So we cancel downloads as soon as we record |
| // all the navigation events we need. |
| void CancelDownloads() { |
| std::vector<raw_ptr<DownloadItem, VectorExperimental>> download_items; |
| content::DownloadManager* manager = |
| browser()->profile()->GetDownloadManager(); |
| manager->GetAllDownloads(&download_items); |
| for (download::DownloadItem* item : download_items) { |
| if (!item->IsDone()) |
| item->Cancel(true); |
| } |
| } |
| |
| DownloadItem* GetDownload() { |
| std::vector<raw_ptr<DownloadItem, VectorExperimental>> download_items; |
| content::DownloadManager* manager = |
| browser()->profile()->GetDownloadManager(); |
| manager->GetAllDownloads(&download_items); |
| if (download_items.empty()) |
| DownloadItemCreatedObserver(manager).WaitForDownloadItem(&download_items); |
| EXPECT_EQ(1U, download_items.size()); |
| return download_items[0]; |
| } |
| |
| // This function needs javascript support from the test page hosted at |
| // |page_url|. It calls "clickLink(..)" javascript function to "click" on the |
| // html element with ID specified by |element_id|, and waits for |
| // |number_of_navigations| to complete. If a |subframe_index| is specified, |
| // |element_id| is assumed to be in corresponding subframe of the test page, |
| // and the javascript function is executed that subframe. |
| void ClickTestLink(const char* element_id, |
| int number_of_navigations, |
| const GURL& page_url, |
| int subframe_index = -1) { |
| TabStripModel* tab_strip = browser()->tab_strip_model(); |
| content::WebContents* current_web_contents = |
| tab_strip->GetActiveWebContents(); |
| ASSERT_TRUE(content::WaitForLoadStop(current_web_contents)); |
| content::TestNavigationObserver navigation_observer( |
| current_web_contents, number_of_navigations, |
| content::MessageLoopRunner::QuitMode::DEFERRED); |
| navigation_observer.StartWatchingNewWebContents(); |
| // Execute test. |
| { |
| std::string script = base::StringPrintf("clickLink('%s');", element_id); |
| content::RenderFrameHost* script_executing_frame = |
| current_web_contents->GetPrimaryMainFrame(); |
| if (subframe_index != -1) { |
| script_executing_frame = |
| ChildFrameAt(script_executing_frame, subframe_index); |
| } |
| ASSERT_TRUE(content::ExecJs(script_executing_frame, script)); |
| } |
| // Wait for navigations on current tab and new tab (if any) to finish. |
| navigation_observer.Wait(); |
| navigation_observer.StopWatchingNewWebContents(); |
| |
| // Since this test uses javascript to mimic clicking on a link (no actual |
| // user gesture), and DidGetUserInteraction() does not respond to |
| // ExecJs(), navigation_transition field in resulting |
| // NavigationEvents will always be RENDERER_INITIATED_WITHOUT_USER_GESTURE. |
| // Therefore, we need to make some adjustment to relevant NavigationEvent. |
| for (std::size_t i = 0U; |
| i < navigation_event_list()->NavigationEventsSize(); i++) { |
| auto* nav_event = navigation_event_list()->GetNavigationEvent(i); |
| if (nav_event->source_url == page_url) { |
| nav_event->navigation_initiation = |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE; |
| return; |
| } |
| } |
| } |
| |
| // Same functionality as |ClickTestLink|, but doesn't wait for the navigation |
| // to complete. |
| void ClickTestLinkPending(const char* element_id, |
| int number_of_navigations, |
| const GURL& page_url, |
| int subframe_index = -1) { |
| TabStripModel* tab_strip = browser()->tab_strip_model(); |
| content::WebContents* current_web_contents = |
| tab_strip->GetActiveWebContents(); |
| ASSERT_TRUE(content::WaitForLoadStop(current_web_contents)); |
| // Execute test. |
| { |
| std::string script = base::StringPrintf("clickLink('%s');", element_id); |
| content::RenderFrameHost* script_executing_frame = |
| current_web_contents->GetPrimaryMainFrame(); |
| if (subframe_index != -1) { |
| script_executing_frame = |
| ChildFrameAt(script_executing_frame, subframe_index); |
| } |
| ASSERT_TRUE(content::ExecJs(script_executing_frame, script)); |
| } |
| |
| // Since this test uses javascript to mimic clicking on a link (no actual |
| // user gesture), and DidGetUserInteraction() does not respond to |
| // ExecJs(), navigation_transition field in resulting |
| // NavigationEvents will always be RENDERER_INITIATED_WITHOUT_USER_GESTURE. |
| // Therefore, we need to make some adjustment to relevant |
| // PendingNavigationEvent. |
| for (auto& it : navigation_event_list()->pending_navigation_events()) { |
| if (it.second->source_url == page_url) { |
| it.second->navigation_initiation = |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE; |
| return; |
| } |
| } |
| } |
| |
| void TriggerDownloadViaHtml5FileApi() { |
| std::vector<raw_ptr<DownloadItem, VectorExperimental>> items; |
| content::DownloadManager* manager = |
| browser()->profile()->GetDownloadManager(); |
| content::WebContents* current_web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| ASSERT_TRUE(content::ExecJs(current_web_contents, "downloadViaFileApi()")); |
| manager->GetAllDownloads(&items); |
| ASSERT_EQ(0U, items.size()); |
| } |
| |
| void VerifyNavigationEvent(const GURL& expected_source_url, |
| const GURL& expected_source_main_frame_url, |
| const GURL& expected_original_request_url, |
| const GURL& expected_destination_url, |
| bool expected_is_user_initiated, |
| bool expected_has_committed, |
| bool expected_has_server_redirect, |
| NavigationEvent* actual_nav_event) { |
| EXPECT_EQ(expected_source_url, actual_nav_event->source_url); |
| EXPECT_EQ(expected_source_main_frame_url, |
| actual_nav_event->source_main_frame_url); |
| EXPECT_EQ(expected_original_request_url, |
| actual_nav_event->original_request_url); |
| EXPECT_EQ(expected_destination_url, actual_nav_event->GetDestinationUrl()); |
| EXPECT_EQ(expected_is_user_initiated, actual_nav_event->IsUserInitiated()); |
| EXPECT_EQ(expected_has_committed, actual_nav_event->has_committed); |
| EXPECT_EQ(expected_has_server_redirect, |
| !actual_nav_event->server_redirect_urls.empty()); |
| } |
| |
| void VerifyReferrerChainEntry( |
| const GURL& expected_url, |
| const GURL& expected_main_frame_url, |
| ReferrerChainEntry::URLType expected_type, |
| const std::string& expected_ip_address, |
| const GURL& expected_referrer_url, |
| const GURL& expected_referrer_main_frame_url, |
| bool expected_is_retargeting, |
| const std::vector<GURL>& expected_server_redirects, |
| ReferrerChainEntry::NavigationInitiation expected_navigation_initiation, |
| const ReferrerChainEntry& actual_entry) { |
| EXPECT_EQ(expected_url.spec(), actual_entry.url()); |
| if (expected_main_frame_url.is_empty()) { |
| EXPECT_FALSE(actual_entry.has_main_frame_url()); |
| } else { |
| // main_frame_url only set if it is different from url. |
| EXPECT_EQ(expected_main_frame_url.spec(), actual_entry.main_frame_url()); |
| EXPECT_NE(expected_main_frame_url.spec(), actual_entry.url()); |
| } |
| EXPECT_EQ(expected_type, actual_entry.type()); |
| if (expected_ip_address.empty()) { |
| ASSERT_EQ(0, actual_entry.ip_addresses_size()); |
| } else { |
| ASSERT_EQ(1, actual_entry.ip_addresses_size()); |
| EXPECT_EQ(expected_ip_address, actual_entry.ip_addresses(0)); |
| } |
| EXPECT_EQ(expected_referrer_url.spec(), actual_entry.referrer_url()); |
| if (expected_referrer_main_frame_url.is_empty()) { |
| EXPECT_FALSE(actual_entry.has_referrer_main_frame_url()); |
| } else { |
| // referrer_main_frame_url only set if it is different from referrer_url. |
| EXPECT_EQ(expected_referrer_main_frame_url.spec(), |
| actual_entry.referrer_main_frame_url()); |
| EXPECT_NE(expected_referrer_main_frame_url.spec(), |
| actual_entry.referrer_url()); |
| } |
| EXPECT_EQ(expected_is_retargeting, actual_entry.is_retargeting()); |
| if (expected_server_redirects.empty()) { |
| EXPECT_EQ(0, actual_entry.server_redirect_chain_size()); |
| } else { |
| ASSERT_EQ(static_cast<int>(expected_server_redirects.size()), |
| actual_entry.server_redirect_chain_size()); |
| for (int i = 0; i < actual_entry.server_redirect_chain_size(); i++) { |
| EXPECT_EQ(expected_server_redirects[i].spec(), |
| actual_entry.server_redirect_chain(i).url()); |
| } |
| } |
| EXPECT_EQ(expected_navigation_initiation, |
| actual_entry.navigation_initiation()); |
| } |
| |
| // Identify referrer chain of a DownloadItem and populate |referrer_chain|. |
| void IdentifyReferrerChainForDownload( |
| DownloadItem* download, |
| ReferrerChain* referrer_chain) { |
| SessionID download_tab_id = sessions::SessionTabHelper::IdForTab( |
| content::DownloadItemUtils::GetWebContents(download)); |
| content::RenderFrameHost* rfh = |
| content::DownloadItemUtils::GetRenderFrameHost(download); |
| content::GlobalRenderFrameHostId outermost_main_frame_id; |
| if (rfh) |
| outermost_main_frame_id = rfh->GetOutermostMainFrame()->GetGlobalId(); |
| |
| auto result = observer_manager_->IdentifyReferrerChainByEventURL( |
| download->GetURL(), download_tab_id, outermost_main_frame_id, |
| 2, // kDownloadAttributionUserGestureLimit |
| referrer_chain); |
| if (result == |
| SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND) { |
| DCHECK_EQ(0, referrer_chain->size()); |
| observer_manager_->IdentifyReferrerChainByRenderFrameHost( |
| rfh, |
| 2, // kDownloadAttributionUserGestureLimit |
| referrer_chain); |
| } |
| } |
| |
| void IdentifyReferrerChainForWebContents(content::WebContents* web_contents, |
| ReferrerChain* referrer_chain) { |
| observer_manager_->IdentifyReferrerChainByRenderFrameHost( |
| // We will assume the primary main frame here. |
| web_contents->GetPrimaryMainFrame(), |
| 2, // kDownloadAttributionUserGestureLimit |
| referrer_chain); |
| } |
| |
| void IdentifyReferrerChainByEventURL( |
| const GURL& event_url, |
| SessionID event_tab_id, // Invalid if tab id is unknown or not available. |
| const content::GlobalRenderFrameHostId& |
| event_outermost_main_frame_id, // Can also be Invalid. |
| ReferrerChain* out_referrer_chain) { |
| observer_manager_->IdentifyReferrerChainByEventURL( |
| event_url, event_tab_id, event_outermost_main_frame_id, |
| 2, // user_gesture_count_limit |
| out_referrer_chain); |
| } |
| |
| void VerifyHostToIpMap() { |
| // Since all testing pages have the same host, there is only one entry in |
| // host_to_ip_map_. |
| SafeBrowsingNavigationObserverManager::HostToIpMap* actual_host_ip_map = |
| host_to_ip_map(); |
| ASSERT_EQ(1U, actual_host_ip_map->size()); |
| auto ip_list = |
| (*actual_host_ip_map)[embedded_test_server()->base_url().host()]; |
| ASSERT_EQ(1U, ip_list.size()); |
| EXPECT_EQ(embedded_test_server()->host_port_pair().host(), |
| ip_list.back().ip); |
| } |
| |
| void SimulateUserGesture() { |
| observer_manager_->RecordUserGestureForWebContents( |
| browser()->tab_strip_model()->GetActiveWebContents()); |
| } |
| |
| NavigationEventList* navigation_event_list() { |
| return observer_manager_->navigation_event_list(); |
| } |
| |
| SafeBrowsingNavigationObserverManager::HostToIpMap* host_to_ip_map() { |
| return observer_manager_->host_to_ip_map(); |
| } |
| |
| int CountOfRecentNavigationsToAppend( |
| bool enhanced_protection_enabled, |
| bool is_incognito, |
| SafeBrowsingNavigationObserverManager::AttributionResult result) { |
| SetEnhancedProtectionPrefForTests(browser()->profile()->GetPrefs(), |
| enhanced_protection_enabled); |
| auto* maybe_otr_profile = is_incognito |
| ? browser()->profile()->GetPrimaryOTRProfile( |
| /*create_if_needed=*/true) |
| : browser()->profile(); |
| return SafeBrowsingNavigationObserverManager:: |
| CountOfRecentNavigationsToAppend(maybe_otr_profile, |
| maybe_otr_profile->GetPrefs(), result); |
| } |
| |
| void AppendRecentNavigations(int recent_navigation_count, |
| ReferrerChain* out_referrer_chain) { |
| observer_manager_->AppendRecentNavigations(recent_navigation_count, |
| out_referrer_chain); |
| } |
| |
| NavigationEvent* GetNavigationEvent(size_t index) { |
| return observer_manager_->navigation_event_list() |
| ->navigation_events()[index] |
| .get(); |
| } |
| |
| std::optional<size_t> FindNavigationEventIndex( |
| const GURL& target_url, |
| content::GlobalRenderFrameHostId outermost_main_frame_id) { |
| return observer_manager_->navigation_event_list()->FindNavigationEvent( |
| base::Time::Now(), target_url, GURL(), SessionID::InvalidValue(), |
| outermost_main_frame_id, |
| (observer_manager_->navigation_event_list()->NavigationEventsSize() - |
| 1)); |
| } |
| |
| void FindAndAddNavigationToReferrerChain(ReferrerChain* referrer_chain, |
| const GURL& target_url) { |
| auto nav_event_index = FindNavigationEventIndex( |
| target_url, content::GlobalRenderFrameHostId()); |
| if (nav_event_index) { |
| auto* nav_event = |
| observer_manager_->navigation_event_list()->GetNavigationEvent( |
| *nav_event_index); |
| observer_manager_->MaybeAddToReferrerChain( |
| referrer_chain, nav_event, GURL(), ReferrerChainEntry::EVENT_URL); |
| } |
| } |
| |
| protected: |
| std::unique_ptr<TestSafeBrowsingNavigationObserverManager> observer_manager_; |
| |
| content::test::PrerenderTestHelper& prerender_helper() { |
| return prerender_helper_; |
| } |
| |
| content::test::FencedFrameTestHelper& fenced_frame_helper() { |
| return fenced_frame_helper_; |
| } |
| |
| private: |
| content::test::PrerenderTestHelper prerender_helper_; |
| content::test::FencedFrameTestHelper fenced_frame_helper_; |
| }; |
| |
| // Type download URL into address bar and start download on the same page. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, TypeInURLDownload) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kDownloadItemURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(2U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(1, referrer_chain.size()); |
| VerifyReferrerChainEntry(download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(0)); |
| } |
| // Click on a link and start download on the same page. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, DirectDownload) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("direct_download", 1, initial_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(2U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| EXPECT_FALSE(referrer_chain.Get(0).is_url_removed_by_policy()); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| EXPECT_FALSE(referrer_chain.Get(1).is_url_removed_by_policy()); |
| } |
| |
| // Click on a link with rel="noreferrer" attribute, and start download on the |
| // same page. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| DirectDownloadNoReferrer) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("direct_download_noreferrer", 1, initial_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(2U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| } |
| |
| // Click on a link with rel="noreferrer" attribute, and start download in a |
| // new tab using target=_blank. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| DirectDownloadNoReferrerTargetBlank) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("direct_download_noreferrer_target_blank", 1, initial_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(3U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| // The next NavigationEvent opens a new tab. |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| // This one is the actual navigation which triggers download. |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| } |
| |
| // Click on a link which navigates to a page then redirects to a download using |
| // META HTTP-EQUIV="refresh". All transitions happen in the same tab. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| SingleMetaRefreshRedirect) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("single_meta_refresh_redirect", 2, initial_url); |
| GURL redirect_url = embedded_test_server()->GetURL(kRedirectURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| // Since unlike server redirects client redirects commit and then generate a |
| // second navigation, our observer records two NavigationEvents for this test. |
| ASSERT_EQ(3U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| redirect_url, // original_request_url |
| redirect_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(redirect_url, // source_url |
| redirect_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(3, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| redirect_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(2)); |
| } |
| |
| // Click on a link which navigates to a page then redirects to a download using |
| // META HTTP-EQUIV="refresh". First navigation happens in target blank. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| SingleMetaRefreshRedirectTargetBlank) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("single_meta_refresh_redirect_target_blank", 2, initial_url); |
| GURL redirect_url = embedded_test_server()->GetURL(kRedirectURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(4U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| redirect_url, // original_request_url |
| redirect_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| redirect_url, // original_request_url |
| redirect_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(redirect_url, // source_url |
| redirect_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(3, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| redirect_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(2)); |
| } |
| |
| // Click on a link which redirects twice before reaching download using |
| // META HTTP-EQUIV="refresh". All transitions happen in the same tab. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| MultiMetaRefreshRedirects) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("multiple_meta_refresh_redirects", 3, initial_url); |
| GURL first_redirect_url = embedded_test_server()->GetURL( |
| "/safe_browsing/download_protection/navigation_observer/" |
| "double_redirect.html"); |
| GURL second_redirect_url = embedded_test_server()->GetURL(kRedirectURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(4U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| first_redirect_url, // original_request_url |
| first_redirect_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(first_redirect_url, // source_url |
| first_redirect_url, // source_main_frame_url |
| second_redirect_url, // original_request_url |
| second_redirect_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(second_redirect_url, // source_url |
| second_redirect_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(4, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| second_redirect_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| second_redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| first_redirect_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| first_redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(3)); |
| } |
| |
| // Click on a link which redirects to download using window.location. |
| // All transitions happen in the same tab. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| WindowLocationRedirect) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("window_location_redirection", 1, initial_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(2U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| } |
| |
| // Click on a link which redirects twice until it reaches download using a |
| // mixture of meta refresh and window.location. All transitions happen in the |
| // same tab. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, MixRedirects) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("mix_redirects", 2, initial_url); |
| GURL redirect_url = embedded_test_server()->GetURL(kRedirectURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(3U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| redirect_url, // original_request_url |
| redirect_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(redirect_url, // source_url |
| redirect_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(3, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| redirect_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(2)); |
| } |
| |
| // Use javascript to open download in a new tab. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, NewTabDownload) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("new_tab_download", 2, initial_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| GURL blank_url = GURL(url::kAboutBlankURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(4U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| blank_url, // original_request_url |
| blank_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| // Source and target are at different tabs. |
| EXPECT_NE(nav_list->GetNavigationEvent(1)->source_tab_id, |
| nav_list->GetNavigationEvent(1)->target_tab_id); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| blank_url, // original_request_url |
| blank_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| EXPECT_EQ(nav_list->GetNavigationEvent(2)->source_tab_id, |
| nav_list->GetNavigationEvent(2)->target_tab_id); |
| VerifyNavigationEvent(blank_url, // source_url |
| blank_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| EXPECT_EQ(nav_list->GetNavigationEvent(3)->source_tab_id, |
| nav_list->GetNavigationEvent(3)->target_tab_id); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(3, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| blank_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| blank_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| "", // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(2)); |
| } |
| |
| // Use javascript to open download in a new tab and download has a data url. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| NewTabDownloadWithDataURL) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("new_tab_download_with_data_url", 2, initial_url); |
| GURL download_url = GURL(kDownloadDataURL); |
| GURL short_download_url = GURL(kShortDataURL); |
| GURL blank_url = GURL(url::kAboutBlankURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(4U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| // The second navigation event is a retargeting navigation. |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| blank_url, // original_request_url |
| blank_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| // Source and target are at different tabs. |
| EXPECT_FALSE(nav_list->GetNavigationEvent(1)->source_tab_id == |
| nav_list->GetNavigationEvent(1)->target_tab_id); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| blank_url, // original_request_url |
| blank_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| EXPECT_EQ(nav_list->GetNavigationEvent(2)->source_tab_id, |
| nav_list->GetNavigationEvent(2)->target_tab_id); |
| VerifyNavigationEvent(blank_url, // source_url |
| blank_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| EXPECT_EQ(nav_list->GetNavigationEvent(3)->source_tab_id, |
| nav_list->GetNavigationEvent(3)->target_tab_id); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(3, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| short_download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| "", // ip_address |
| blank_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| blank_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| "", // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(2)); |
| } |
| |
| // Click a link in a subframe and start download. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| SubFrameDirectDownload) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("sub_frame_download_attribution", 1, initial_url); |
| GURL multi_frame_test_url = |
| embedded_test_server()->GetURL(kMultiFrameTestURL); |
| GURL iframe_url = embedded_test_server()->GetURL(kIframeDirectDownloadURL); |
| ClickTestLink("iframe_direct_download", 1, iframe_url, 0); |
| GURL iframe_retargeting_url = |
| embedded_test_server()->GetURL(kIframeRetargetingURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(5U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| multi_frame_test_url, // original_request_url |
| multi_frame_test_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| // The order of the next two navigation events may vary. We check for both |
| // possibilities. Their order doesn't impact referrer chain attribution logic. |
| if (nav_list->GetNavigationEvent(2)->original_request_url == iframe_url) { |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_url, // original_request_url |
| iframe_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_retargeting_url, // original_request_url |
| iframe_retargeting_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| } else { |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_retargeting_url, // original_request_url |
| iframe_retargeting_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_url, // original_request_url |
| iframe_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| } |
| VerifyNavigationEvent(iframe_url, // source_url |
| multi_frame_test_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(4)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(4, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| iframe_url, // referrer_url |
| multi_frame_test_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| iframe_url, // url |
| multi_frame_test_url, // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| multi_frame_test_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| multi_frame_test_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(3)); |
| } |
| |
| // Click a link in a subframe and open download in a new tab. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| SubFrameNewTabDownload) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("sub_frame_download_attribution", 1, initial_url); |
| GURL multi_frame_test_url = |
| embedded_test_server()->GetURL(kMultiFrameTestURL); |
| GURL iframe_url = embedded_test_server()->GetURL(kIframeDirectDownloadURL); |
| GURL iframe_retargeting_url = |
| embedded_test_server()->GetURL(kIframeRetargetingURL); |
| ClickTestLink("iframe_new_tab_download", 2, iframe_retargeting_url, 1); |
| GURL blank_url = GURL(url::kAboutBlankURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(7U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| multi_frame_test_url, // original_request_url |
| multi_frame_test_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| // The order of the next two navigation events may vary. We check for both |
| // possibilities. Their order doesn't impact referrer chain attribution logic. |
| if (nav_list->GetNavigationEvent(2)->original_request_url == iframe_url) { |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_url, // original_request_url |
| iframe_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_retargeting_url, // original_request_url |
| iframe_retargeting_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| } else { |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_retargeting_url, // original_request_url |
| iframe_retargeting_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(GURL(), // source_url |
| multi_frame_test_url, // source_main_frame_url |
| iframe_url, // original_request_url |
| iframe_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| } |
| VerifyNavigationEvent(iframe_retargeting_url, // source_url |
| multi_frame_test_url, // source_main_frame_url |
| blank_url, // original_request_url |
| blank_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(4)); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| blank_url, // original_request_url |
| blank_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(5)); |
| VerifyNavigationEvent(blank_url, // source_url |
| blank_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(6)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| EXPECT_EQ(5, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| blank_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| blank_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| "", // ip_address |
| iframe_retargeting_url, // referrer_url |
| multi_frame_test_url, // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| iframe_retargeting_url, // url |
| multi_frame_test_url, // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| multi_frame_test_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(2)); |
| VerifyReferrerChainEntry( |
| multi_frame_test_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(3)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(4)); |
| } |
| |
| // Click a link which redirects to the landing page, and then click on the |
| // landing page to trigger download. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, CompleteReferrerChain) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("complete_referrer_chain", 2, initial_url); |
| GURL redirect_url = embedded_test_server()->GetURL(kRedirectToLandingURL); |
| GURL landing_url = embedded_test_server()->GetURL(kLandingURL); |
| ClickTestLink("download_on_landing_page", 1, landing_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(4U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| redirect_url, // original_request_url |
| redirect_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(redirect_url, // source_url |
| redirect_url, // source_main_frame_url |
| landing_url, // original_request_url |
| landing_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(landing_url, // source_url |
| landing_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| EXPECT_EQ(4, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| landing_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| landing_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| redirect_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| VerifyReferrerChainEntry( |
| initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url is empty since this beyonds 2 clicks. |
| GURL(), // referrer_main_frame_url is empty for the same reason. |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, referrer_chain.Get(3)); |
| } |
| |
| // Click three links before reaching download. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| ReferrerAttributionWithinTwoUserGestures) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("attribution_within_two_user_gestures", 1, initial_url); |
| GURL page_before_landing_referrer_url = |
| embedded_test_server()->GetURL(kPageBeforeLandingReferrerURL); |
| ClickTestLink("link_to_landing_referrer", 1, |
| page_before_landing_referrer_url); |
| GURL landing_referrer_url = |
| embedded_test_server()->GetURL(kLandingReferrerURL); |
| ClickTestLink("link_to_landing", 1, landing_referrer_url); |
| GURL landing_url = embedded_test_server()->GetURL(kLandingURL); |
| ClickTestLink("download_on_landing_page", 1, landing_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(5U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| page_before_landing_referrer_url, // original_request |
| page_before_landing_referrer_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(page_before_landing_referrer_url, // source_url |
| page_before_landing_referrer_url, // source_main_frame |
| landing_referrer_url, // original_request_url |
| landing_referrer_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(landing_referrer_url, // source_url |
| landing_referrer_url, // source_main_frame |
| landing_url, // original_request_url |
| landing_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| VerifyNavigationEvent(landing_url, // source_url |
| landing_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(4)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| EXPECT_EQ(3, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| landing_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| landing_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| landing_referrer_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| landing_referrer_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url is empty since this beyonds 2 clicks. |
| GURL(), // referrer_main_frame_url is empty for the same reason. |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| // page_before_landing_referrer_url is not in referrer chain. |
| } |
| |
| // Server-side redirect. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, ServerRedirect) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| GURL request_url = |
| embedded_test_server()->GetURL("/server-redirect?" + download_url.spec()); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), request_url)); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(2U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| request_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| true, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(1, referrer_chain.size()); |
| VerifyReferrerChainEntry(download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| {request_url, download_url}, // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(0)); |
| } |
| |
| // 2 consecutive server-side redirects. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, TwoServerRedirects) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL destination_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| GURL redirect_url = embedded_test_server()->GetURL("/server-redirect?" + |
| destination_url.spec()); |
| GURL request_url = |
| embedded_test_server()->GetURL("/server-redirect?" + redirect_url.spec()); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), request_url)); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(2U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| request_url, // original_request_url |
| destination_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| true, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| const auto redirect_vector = |
| nav_list->GetNavigationEvent(1)->server_redirect_urls; |
| ASSERT_EQ(2U, redirect_vector.size()); |
| EXPECT_EQ(redirect_url, redirect_vector[0]); |
| EXPECT_EQ(destination_url, redirect_vector[1]); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(1, referrer_chain.size()); |
| VerifyReferrerChainEntry(destination_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| {request_url, redirect_url, destination_url}, |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(0)); |
| } |
| |
| // Retargeting immediately followed by server-side redirect. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| RetargetingAndServerRedirect) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| GURL request_url = |
| embedded_test_server()->GetURL("/server-redirect?" + download_url.spec()); |
| ClickTestLink("new_tab_download_with_server_redirect", 1, initial_url); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(3U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| request_url, // original_request_url |
| request_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| request_url, // original_request_url |
| download_url, // destination_url |
| false, // is_user_initiated, |
| false, // has_committed |
| true, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| {request_url, download_url}, // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| } |
| |
| // host_to_ip_map_ size should increase by one after a new navigation. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, AddIPMapping) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| auto* ip_map = host_to_ip_map(); |
| std::string test_server_host(embedded_test_server()->base_url().host()); |
| ip_map->clear(); |
| ip_map->insert( |
| std::make_pair(test_server_host, std::vector<ResolvedIPAddress>())); |
| ASSERT_EQ(std::size_t(0), (*ip_map)[test_server_host].size()); |
| ClickTestLink("direct_download", 1, initial_url); |
| EXPECT_EQ(1U, (*ip_map)[test_server_host].size()); |
| EXPECT_EQ(embedded_test_server()->host_port_pair().host(), |
| (*ip_map)[test_server_host].back().ip); |
| } |
| |
| // If we have already seen an IP associated with a host, update its timestamp. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, IPListDedup) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| auto* ip_map = host_to_ip_map(); |
| ip_map->clear(); |
| std::string test_server_host(embedded_test_server()->base_url().host()); |
| ip_map->insert( |
| std::make_pair(test_server_host, std::vector<ResolvedIPAddress>())); |
| base::Time yesterday(base::Time::Now() - base::Days(1)); |
| (*ip_map)[test_server_host].push_back(ResolvedIPAddress( |
| yesterday, embedded_test_server()->host_port_pair().host())); |
| ASSERT_EQ(1U, (*ip_map)[test_server_host].size()); |
| ClickTestLink("direct_download", 1, initial_url); |
| EXPECT_EQ(1U, (*ip_map)[test_server_host].size()); |
| EXPECT_EQ(embedded_test_server()->host_port_pair().host(), |
| (*ip_map)[test_server_host].back().ip); |
| EXPECT_NE(yesterday, (*ip_map)[test_server_host].front().timestamp); |
| } |
| |
| // Download via html5 file API. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| DownloadViaHTML5FileApi) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL hosting_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| TriggerDownloadViaHtml5FileApi(); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(1U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| hosting_url, // original_request_url |
| hosting_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyHostToIpMap(); |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(1, referrer_chain.size()); |
| |
| VerifyReferrerChainEntry(hosting_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(0)); |
| } |
| |
| // Verify referrer chain when there are URL fragments. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| DownloadAttributionWithURLFragment) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| // Clicks on link and navigates to ".../page_before_landing_referrer.html". |
| ClickTestLink("attribution_should_ignore_url_fragments", 1, initial_url); |
| GURL expected_page_before_landing_referrer_url = |
| embedded_test_server()->GetURL(kPageBeforeLandingReferrerURL); |
| // Clicks on link and navigates to ".../landing_referrer.html?bar=foo#baz". |
| ClickTestLink("link_to_landing_referrer_with_query_and_fragment", 1, |
| expected_page_before_landing_referrer_url); |
| GURL expected_landing_referrer_url_with_query = |
| embedded_test_server()->GetURL(kLandingReferrerURLWithQuery); |
| // Clicks on link and navigates to ".../landing.html#". |
| ClickTestLink("link_to_landing_with_empty_fragment", 1, |
| expected_landing_referrer_url_with_query); |
| GURL expected_landing_url = embedded_test_server()->GetURL(kLandingURL); |
| |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_EQ(4U, nav_list->NavigationEventsSize()); |
| |
| ReferrerChain referrer_chain; |
| SimulateUserGesture(); |
| IdentifyReferrerChainForWebContents( |
| browser()->tab_strip_model()->GetActiveWebContents(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| |
| // Verify url fragment is cleared in referrer chain. |
| VerifyReferrerChainEntry( |
| expected_landing_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| expected_landing_referrer_url_with_query, |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| expected_landing_referrer_url_with_query, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url is empty since this beyonds 2 clicks. |
| GURL(), // referrer_main_frame_url is empty for the same reason. |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| VerifySanitizeReferrerChain) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL test_server_origin = |
| embedded_test_server()->base_url().DeprecatedGetOriginAsURL(); |
| ClickTestLink("direct_download", 1, initial_url); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(2U, nav_list->NavigationEventsSize()); |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| SafeBrowsingNavigationObserverManager::SanitizeReferrerChain(&referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| test_server_origin, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| test_server_origin, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry(test_server_origin, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| VerifyNumberOfRecentNavigationsToCollect) { |
| EXPECT_EQ(0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::SUCCESS)); |
| EXPECT_EQ(0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::SUCCESS)); |
| EXPECT_EQ(0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); |
| EXPECT_EQ(0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); |
| EXPECT_EQ( |
| 0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); |
| EXPECT_EQ( |
| 0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); |
| EXPECT_EQ(0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::INVALID_URL)); |
| EXPECT_EQ(0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::INVALID_URL)); |
| EXPECT_EQ( |
| 0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); |
| EXPECT_EQ( |
| 0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/false, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); |
| |
| EXPECT_EQ(5, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::SUCCESS)); |
| EXPECT_EQ(0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::SUCCESS)); |
| EXPECT_EQ(5, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); |
| EXPECT_EQ(0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_PAGE)); |
| EXPECT_EQ( |
| 0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); |
| EXPECT_EQ( |
| 0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER)); |
| EXPECT_EQ(5, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::INVALID_URL)); |
| EXPECT_EQ(0, CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::INVALID_URL)); |
| EXPECT_EQ( |
| 5, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/false, |
| SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); |
| EXPECT_EQ( |
| 0, |
| CountOfRecentNavigationsToAppend( |
| /*enhanced_protection_enabled=*/true, /*is_incognito=*/true, |
| SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| AppendRecentNavigationsToIncompleteReferrerChain) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("complete_referrer_chain", 2, initial_url); |
| GURL redirect_url = embedded_test_server()->GetURL(kRedirectToLandingURL); |
| GURL landing_url = embedded_test_server()->GetURL(kLandingURL); |
| ClickTestLink("download_on_landing_page", 1, landing_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| |
| ReferrerChain referrer_chain; |
| // Add the download_url to referrer chain. |
| FindAndAddNavigationToReferrerChain(&referrer_chain, download_url); |
| AppendRecentNavigations(/*recent_navigation_count=*/3, &referrer_chain); |
| // Now the resulting referrer chain should contain the download url entry, and |
| // 3 recent navigaitons happened after the download url navigations. |
| EXPECT_EQ(4, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| landing_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| landing_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| redirect_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(3)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| NewWindowAndNavigateSubframe) { |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto main_frame_url = embedded_test_server()->GetURL(kMultiFrameTestURL); |
| auto new_window_url = embedded_test_server()->GetURL(kBasicIframeURL); |
| auto new_window_subframe_url = embedded_test_server()->GetURL(kEmptyURL); |
| auto initial_subframe_url = |
| embedded_test_server()->GetURL(kInitialSubframeUrl); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); |
| |
| auto initiator_outermost_main_frame_id = |
| web_contents()->GetPrimaryMainFrame()->GetGlobalId(); |
| |
| auto* initial_web_contents = web_contents(); |
| |
| ui_test_utils::UrlLoadObserver url_observer(new_window_url); |
| ASSERT_TRUE( |
| ExecJs(web_contents()->GetPrimaryMainFrame(), |
| content::JsReplace("var w = window.open($1, 'New Window');", |
| new_window_url))); |
| url_observer.Wait(); |
| const int kExpectedNumberOfNavigations = 1; |
| |
| content::TestNavigationObserver navigation_observer( |
| web_contents(), kExpectedNumberOfNavigations); |
| ASSERT_TRUE( |
| ExecJs(initial_web_contents->GetPrimaryMainFrame(), |
| content::JsReplace("w.document.querySelector('IFRAME').src = $1;", |
| new_window_subframe_url))); |
| navigation_observer.Wait(); |
| EXPECT_EQ(new_window_subframe_url, navigation_observer.last_navigation_url()); |
| |
| auto target_main_frame_id = |
| web_contents()->GetPrimaryMainFrame()->GetGlobalId(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainByEventURL( |
| new_window_url, sessions::SessionTabHelper::IdForTab(web_contents()), |
| content::GlobalRenderFrameHostId(), &referrer_chain); |
| |
| auto index = FindNavigationEventIndex(new_window_url, |
| content::GlobalRenderFrameHostId()); |
| ASSERT_TRUE(index); |
| auto* nav_event = GetNavigationEvent(*index); |
| EXPECT_EQ(initiator_outermost_main_frame_id, |
| nav_event->initiator_outermost_main_frame_id); |
| EXPECT_EQ(target_main_frame_id, nav_event->outermost_main_frame_id); |
| |
| EXPECT_EQ(2, referrer_chain.size()); |
| |
| referrer_chain.Clear(); |
| IdentifyReferrerChainByEventURL( |
| new_window_subframe_url, |
| sessions::SessionTabHelper::IdForTab(web_contents()), |
| content::GlobalRenderFrameHostId(), &referrer_chain); |
| EXPECT_EQ(4, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| new_window_subframe_url, // url |
| // TODO(crbug.com/40823953): this should be |new_window_url|. |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| initial_subframe_url, // referrer_url |
| new_window_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| |
| VerifyReferrerChainEntry( |
| initial_subframe_url, // url |
| new_window_url, // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| new_window_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| |
| VerifyReferrerChainEntry( |
| new_window_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| main_frame_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(2)); |
| |
| VerifyReferrerChainEntry(main_frame_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(3)); |
| |
| index = FindNavigationEventIndex(new_window_subframe_url, |
| content::GlobalRenderFrameHostId()); |
| ASSERT_TRUE(index); |
| nav_event = GetNavigationEvent(*index); |
| EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetGlobalId(), |
| nav_event->outermost_main_frame_id); |
| |
| // If the initial main frame runs JS to initiate this subframe navigation, the |
| // the navigation request's initiator frame is in the current frame tree, |
| // not the frame in which the JS ran. |
| EXPECT_EQ(web_contents()->GetPrimaryMainFrame()->GetGlobalId(), |
| nav_event->initiator_outermost_main_frame_id); |
| } |
| |
| // This is similar to PrerenderReferrerChains, but navigates rather than |
| // initiating the prerender to ensure that the referrer chains match. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| ReferrerChainsMatchPrerender) { |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto main_frame_url = embedded_test_server()->GetURL(kMultiFrameTestURL); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); |
| |
| auto next_url = embedded_test_server()->GetURL(kSubFrameTestURL); |
| content::TestNavigationObserver observer(web_contents(), 1); |
| ASSERT_TRUE(ExecJs(web_contents(), |
| content::JsReplace("window.location = $1;", next_url))); |
| observer.Wait(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainByEventURL( |
| next_url, sessions::SessionTabHelper::IdForTab(web_contents()), |
| web_contents()->GetPrimaryMainFrame()->GetGlobalId(), &referrer_chain); |
| |
| EXPECT_EQ(2, referrer_chain.size()); |
| |
| VerifyReferrerChainEntry( |
| next_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| main_frame_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| |
| VerifyReferrerChainEntry(main_frame_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| PrerenderReferrerChains) { |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto main_frame_url = embedded_test_server()->GetURL(kMultiFrameTestURL); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); |
| |
| auto prerendered_url = embedded_test_server()->GetURL(kSubFrameTestURL); |
| auto host_id = prerender_helper().AddPrerender(prerendered_url); |
| prerender_helper().WaitForPrerenderLoadCompletion(prerendered_url); |
| |
| // The prerendered URL (iframe.html) will now be loaded twice within the |
| // WebContents. Once as the main frame of the prerendered page and once as a |
| // subframe of the primary page. Since the prerender was initiated after |
| // loading the primary page, it will be the most recent navigation event. |
| |
| // Should find the event corresponding to the prerendered page. By passing an |
| // invalid RFH id, FindNavigationEvent does not attempt to match within a |
| // given outermost main frame but will instead match the most recent matching |
| // navigation event. |
| auto index_a = FindNavigationEventIndex(prerendered_url, |
| content::GlobalRenderFrameHostId()); |
| |
| // Since we're supplying the id for the primary page's outermost main frame, |
| // we should find the event for the primary page. |
| auto index_b = FindNavigationEventIndex( |
| prerendered_url, web_contents()->GetPrimaryMainFrame()->GetGlobalId()); |
| |
| // Ensure that these indices are valid and not equal. |
| EXPECT_TRUE(index_a && index_b); |
| EXPECT_NE(*index_a, *index_b); |
| |
| auto* prerendered_main_frame_host = |
| prerender_helper().GetPrerenderedMainFrameHost(host_id); |
| auto index_c = FindNavigationEventIndex( |
| prerendered_url, |
| prerendered_main_frame_host->GetOutermostMainFrame()->GetGlobalId()); |
| |
| // By explicitly supplying the outermost frame id for the prerendered page, we |
| // should also get the event corresponding to the prerendered page. |
| EXPECT_TRUE(index_c); |
| EXPECT_EQ(*index_a, *index_c); |
| |
| // Build a full referrer chain for the prerendered page. |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainByEventURL( |
| prerendered_url, sessions::SessionTabHelper::IdForTab(web_contents()), |
| prerendered_main_frame_host->GetOutermostMainFrame()->GetGlobalId(), |
| &referrer_chain); |
| |
| EXPECT_EQ(2, referrer_chain.size()); |
| |
| VerifyReferrerChainEntry( |
| prerendered_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| main_frame_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| |
| VerifyReferrerChainEntry(main_frame_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| |
| content::test::PrerenderHostObserver host_observer(*web_contents(), host_id); |
| prerender_helper().NavigatePrimaryPage(prerendered_url); |
| host_observer.WaitForActivation(); |
| |
| // Build a full referrer chain for the prerendered page following activation. |
| referrer_chain.Clear(); |
| IdentifyReferrerChainByEventURL( |
| prerendered_url, sessions::SessionTabHelper::IdForTab(web_contents()), |
| web_contents()->GetPrimaryMainFrame()->GetGlobalId(), &referrer_chain); |
| |
| EXPECT_EQ(2, referrer_chain.size()); |
| |
| VerifyReferrerChainEntry( |
| prerendered_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| main_frame_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| |
| VerifyReferrerChainEntry(main_frame_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| FencedFrameNavigationEventsAndReferrerChain) { |
| const auto test_server_ip(embedded_test_server()->host_port_pair().host()); |
| const auto main_frame_url = |
| embedded_test_server()->GetURL("a.test", "/title1.html"); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); |
| const auto outermost_rfh_id = |
| web_contents()->GetPrimaryMainFrame()->GetGlobalId(); |
| |
| const auto fenced_frame_gurl = |
| embedded_test_server()->GetURL("b.test", "/fenced_frames/title1.html"); |
| auto* ff_rfh = fenced_frame_helper().CreateFencedFrame( |
| web_contents()->GetPrimaryMainFrame(), fenced_frame_gurl); |
| ASSERT_TRUE(ff_rfh); |
| |
| // Expects the same non-null index. |
| auto index_a = FindNavigationEventIndex(main_frame_url, |
| content::GlobalRenderFrameHostId()); |
| auto index_b = FindNavigationEventIndex(main_frame_url, outermost_rfh_id); |
| ASSERT_TRUE(index_a.has_value()); |
| ASSERT_EQ(index_a, index_b); |
| |
| // Expects the same non-null index. |
| auto index_c = FindNavigationEventIndex(fenced_frame_gurl, |
| content::GlobalRenderFrameHostId()); |
| auto index_d = FindNavigationEventIndex(fenced_frame_gurl, outermost_rfh_id); |
| ASSERT_TRUE(index_c.has_value()); |
| ASSERT_EQ(index_c, index_d); |
| |
| // Main frame initial navigation and fenced frame initial navigation. |
| ASSERT_EQ(navigation_event_list()->NavigationEventsSize(), 2U); |
| // Main frame. |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| main_frame_url, // original_request_url |
| main_frame_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| navigation_event_list()->GetNavigationEvent(0)); |
| // Fenced frame initial navigation. The FencedFrame navigation is not |
| // user-initiated by setting the `src` attribute. |
| VerifyNavigationEvent(GURL(), // source_url |
| main_frame_url, // source_main_frame_url |
| fenced_frame_gurl, // original_request_url |
| fenced_frame_gurl, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| navigation_event_list()->GetNavigationEvent(1)); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainByEventURL( |
| fenced_frame_gurl, sessions::SessionTabHelper::IdForTab(web_contents()), |
| outermost_rfh_id, &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| |
| // The fenced frame's `NavigationEvent` will not have `source_url` because the |
| // last committed URL is empty (coming from `about:blank`), thus the entry's |
| // `referrer_url` is empty. |
| // The `source_main_frame_url` of the event is retrieved from the embedder |
| // page, and since it is different from the `source_url` of the event, it is |
| // stored at the entry's `referrer_main_frame_url`. |
| VerifyReferrerChainEntry( |
| fenced_frame_gurl, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| main_frame_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| |
| VerifyReferrerChainEntry(main_frame_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| |
| // Navigates the fenced frame. |
| const auto fenced_frame_gurl2 = |
| embedded_test_server()->GetURL("c.test", "/fenced_frames/title1.html"); |
| ff_rfh = fenced_frame_helper().NavigateFrameInFencedFrameTree( |
| ff_rfh, fenced_frame_gurl2); |
| ASSERT_TRUE(ff_rfh); |
| |
| // Main frame initial navigation, fenced frame initial navigation and fenced |
| // frame second navigation. |
| ASSERT_EQ(navigation_event_list()->NavigationEventsSize(), 3U); |
| // Main frame. |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| main_frame_url, // original_request_url |
| main_frame_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| navigation_event_list()->GetNavigationEvent(0)); |
| // Fenced frame initial navigation. |
| VerifyNavigationEvent(GURL(), // source_url |
| main_frame_url, // source_main_frame_url |
| fenced_frame_gurl, // original_request_url |
| fenced_frame_gurl, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| navigation_event_list()->GetNavigationEvent(1)); |
| // Fenced frame second navigation. |
| VerifyNavigationEvent(fenced_frame_gurl, // source_url |
| main_frame_url, // source_main_frame_url |
| fenced_frame_gurl2, // original_request_url |
| fenced_frame_gurl2, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| navigation_event_list()->GetNavigationEvent(2)); |
| |
| // Three entries. |
| referrer_chain.Clear(); |
| IdentifyReferrerChainByEventURL( |
| fenced_frame_gurl2, sessions::SessionTabHelper::IdForTab(web_contents()), |
| outermost_rfh_id, &referrer_chain); |
| ASSERT_EQ(3, referrer_chain.size()); |
| |
| // For the second fenced frame navigation, we have a valid `referrer_url`. |
| VerifyReferrerChainEntry( |
| fenced_frame_gurl2, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| fenced_frame_gurl, // referrer_url |
| main_frame_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(0)); |
| |
| // Almost identical to the initial fenced frame navigation entry, except for |
| // that the `type` is `CLIENT_REDIRECT` instead of `EVENT_URL`. Because of the |
| // new `type` we also have a non-empty `main_frame_url`. |
| VerifyReferrerChainEntry( |
| fenced_frame_gurl, // url |
| main_frame_url, // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| main_frame_url, // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| |
| // Same as the main frame entry prior to the second fenced frame navigation. |
| VerifyReferrerChainEntry(main_frame_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(2)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| NavigateBackwardForward) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("complete_referrer_chain", 2, initial_url); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| EXPECT_EQ(3U, nav_list->NavigationEventsSize()); |
| |
| // Simulates back. |
| ASSERT_TRUE( |
| content::ExecJs(browser()->tab_strip_model()->GetActiveWebContents(), |
| "window.history.back();")); |
| base::RunLoop().RunUntilIdle(); |
| |
| // Simulates forward. |
| ASSERT_TRUE( |
| content::ExecJs(browser()->tab_strip_model()->GetActiveWebContents(), |
| "window.history.forward();")); |
| base::RunLoop().RunUntilIdle(); |
| |
| nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| // Verifies navigations caused by back/forward are ignored. |
| EXPECT_EQ(3U, nav_list->NavigationEventsSize()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, ReloadNotRecorded) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| EXPECT_EQ(1U, nav_list->NavigationEventsSize()); |
| |
| // Simulates reload. |
| ASSERT_TRUE( |
| content::ExecJs(browser()->tab_strip_model()->GetActiveWebContents(), |
| "location.reload();")); |
| base::RunLoop().RunUntilIdle(); |
| |
| nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| // Verifies navigations caused by reload are ignored. |
| EXPECT_EQ(1U, nav_list->NavigationEventsSize()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| CreateIframeElementGetsReferrerChain) { |
| GURL initial_url = embedded_test_server()->GetURL(kCreateIframeElementURL); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url)); |
| ClickTestLink("do_download", 1, initial_url); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| SetWindowLocationGetsReferrerChain) { |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url)); |
| |
| ASSERT_TRUE( |
| content::ExecJs(browser()->tab_strip_model()->GetActiveWebContents(), |
| "window.location='../signed.exe'")); |
| base::RunLoop().RunUntilIdle(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(2, referrer_chain.size()); |
| } |
| |
| // Open a new tab to some arbitrary URL, then have the opener navigate the new |
| // tab to the actual landing page where the user then clicks a link to start a |
| // download. |
| // TODO(drubery, mcnee): The "source" information captured in a Safe Browsing |
| // |NavigationEvent| does not necessarily reflect the initiator of a navigation. |
| // This test illustrates this behaviour. Note that |initial_popup_url| appears |
| // to navigate itself to the landing page, even though it was navigated by its |
| // opener. Investigate whether the initiator of a navigation should be reflected |
| // in the referrer chain. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| NewTabClientRedirectByOpener) { |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL initial_popup_url = embedded_test_server()->GetURL("/title1.html"); |
| GURL landing_url = embedded_test_server()->GetURL(kLandingURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url)); |
| |
| content::WebContents* opener_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| |
| ui_test_utils::TabAddedWaiter tab_added(browser()); |
| content::TestNavigationObserver new_tab_nav(initial_popup_url); |
| new_tab_nav.StartWatchingNewWebContents(); |
| SimulateUserGesture(); |
| ASSERT_TRUE(content::ExecJs( |
| opener_contents, content::JsReplace("window.newWindow = window.open($1);", |
| initial_popup_url))); |
| new_tab_nav.Wait(); |
| tab_added.Wait(); |
| |
| content::TestNavigationObserver landing_nav_observer(landing_url); |
| landing_nav_observer.WatchExistingWebContents(); |
| ASSERT_TRUE(content::ExecJs( |
| opener_contents, |
| content::JsReplace("window.newWindow.location = $1;", landing_url))); |
| landing_nav_observer.Wait(); |
| |
| ClickTestLink("download_on_landing_page", 1, landing_url); |
| |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(5U, nav_list->NavigationEventsSize()); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_url, // original_request_url |
| initial_url, // destination_url |
| true, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(0)); |
| VerifyNavigationEvent(initial_url, // source_url |
| initial_url, // source_main_frame_url |
| initial_popup_url, // original_request_url |
| initial_popup_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(1)); |
| VerifyNavigationEvent(GURL(), // source_url |
| GURL(), // source_main_frame_url |
| initial_popup_url, // original_request_url |
| initial_popup_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(2)); |
| VerifyNavigationEvent(initial_popup_url, // source_url |
| initial_popup_url, // source_main_frame_url |
| landing_url, // original_request_url |
| landing_url, // destination_url |
| false, // is_user_initiated, |
| true, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(3)); |
| VerifyNavigationEvent(landing_url, // source_url |
| landing_url, // source_main_frame_url |
| download_url, // original_request_url |
| download_url, // destination_url |
| true, // is_user_initiated, |
| false, // has_committed |
| false, // has_server_redirect |
| nav_list->GetNavigationEvent(4)); |
| VerifyHostToIpMap(); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| EXPECT_EQ(4, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| landing_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| landing_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| initial_popup_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| initial_popup_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(3)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| IdentifyReferrerChainByPendingEventURL_TwoUserGestures) { |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL page_before_landing_referrer_url = |
| embedded_test_server()->GetURL(kPageBeforeLandingReferrerURL); |
| GURL landing_referrer_url = |
| embedded_test_server()->GetURL(kLandingReferrerURL); |
| GURL landing_url = embedded_test_server()->GetURL(kLandingURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url)); |
| |
| ClickTestLink("attribution_within_two_user_gestures", 1, initial_url); |
| |
| ClickTestLink("link_to_landing_referrer", 1, |
| page_before_landing_referrer_url); |
| |
| // Navigate to landing_url. Keep the navigation in pending state so we can |
| // test on the pending event API. |
| content::TestNavigationManager navigation_manager( |
| browser()->tab_strip_model()->GetActiveWebContents(), landing_url); |
| ClickTestLinkPending("link_to_landing", 1, landing_referrer_url); |
| EXPECT_TRUE(navigation_manager.WaitForResponse()); |
| |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(3U, nav_list->NavigationEventsSize()); |
| ASSERT_EQ(1U, nav_list->PendingNavigationEventsSize()); |
| |
| ReferrerChain referrer_chain; |
| auto result = observer_manager_->IdentifyReferrerChainByPendingEventURL( |
| landing_url, |
| /*user_gesture_count_limit=*/2, &referrer_chain); |
| ASSERT_EQ(SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER, |
| result); |
| EXPECT_EQ(3, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| landing_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| landing_referrer_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| VerifyReferrerChainEntry( |
| landing_referrer_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| page_before_landing_referrer_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(1)); |
| VerifyReferrerChainEntry( |
| page_before_landing_referrer_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| |
| navigation_manager.ResumeNavigation(); |
| ASSERT_TRUE(navigation_manager.WaitForNavigationFinished()); |
| ASSERT_EQ(0U, nav_list->PendingNavigationEventsSize()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| IdentifyReferrerChainByPendingEventURL_ServerRedirect) { |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL landing_url = embedded_test_server()->GetURL(kLandingURL); |
| GURL request_url = |
| embedded_test_server()->GetURL("/server-redirect?" + landing_url.spec()); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url)); |
| |
| content::TestNavigationManager navigation_manager( |
| browser()->tab_strip_model()->GetActiveWebContents(), request_url); |
| |
| // Navigate to request_url. Keep the navigation in pending state so we can |
| // test on the pending event API. |
| browser()->tab_strip_model()->GetActiveWebContents()->GetController().LoadURL( |
| request_url, content::Referrer(), ui::PAGE_TRANSITION_LINK, |
| std::string()); |
| EXPECT_TRUE(navigation_manager.WaitForResponse()); |
| |
| auto* nav_list = navigation_event_list(); |
| ASSERT_TRUE(nav_list); |
| ASSERT_EQ(1U, nav_list->PendingNavigationEventsSize()); |
| |
| ReferrerChain referrer_chain; |
| auto result = observer_manager_->IdentifyReferrerChainByPendingEventURL( |
| request_url, |
| /*user_gesture_count_limit=*/2, &referrer_chain); |
| // The navigation event is not found because the destination URL has already |
| // changed to landing_url. |
| ASSERT_EQ(SafeBrowsingNavigationObserverManager::NAVIGATION_EVENT_NOT_FOUND, |
| result); |
| |
| result = observer_manager_->IdentifyReferrerChainByPendingEventURL( |
| landing_url, |
| /*user_gesture_count_limit=*/2, &referrer_chain); |
| ASSERT_EQ(SafeBrowsingNavigationObserverManager::SUCCESS, result); |
| EXPECT_EQ(1, referrer_chain.size()); |
| VerifyReferrerChainEntry(landing_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| true, // is_retargeting |
| {request_url, landing_url}, // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(0)); |
| |
| navigation_manager.ResumeNavigation(); |
| ASSERT_TRUE(navigation_manager.WaitForNavigationFinished()); |
| ASSERT_EQ(0U, nav_list->PendingNavigationEventsSize()); |
| } |
| |
| // Verify URLs that match the Safe Browsing allowlist domains (a.k.a |
| // prefs::kSafeBrowsingAllowlistDomains) are removed from the referrer chain. |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| AllowlistDomainsRemoved_ReferrerChain) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("sub_frame_download_attribution", 1, initial_url); |
| GURL multi_frame_test_url = |
| embedded_test_server()->GetURL(kMultiFrameTestURL); |
| GURL iframe_url = embedded_test_server()->GetURL(kIframeDirectDownloadURL); |
| ClickTestLink("iframe_direct_download", 1, iframe_url, 0); |
| GURL iframe_retargeting_url = |
| embedded_test_server()->GetURL(kIframeRetargetingURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| |
| // Add URLs to the Safe Browsing allowlist. |
| base::Value::List allowlist; |
| allowlist.Append(initial_url.host()); |
| allowlist.Append(multi_frame_test_url.host()); |
| allowlist.Append(iframe_url.host()); |
| allowlist.Append(iframe_retargeting_url.host()); |
| allowlist.Append(download_url.host()); |
| browser()->profile()->GetPrefs()->SetList( |
| prefs::kSafeBrowsingAllowlistDomains, std::move(allowlist)); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(4, referrer_chain.size()); |
| // All URL fields should be empty because they all match the allowlist. |
| VerifyReferrerChainEntry( |
| GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| EXPECT_TRUE(referrer_chain.Get(0).is_url_removed_by_policy()); |
| VerifyReferrerChainEntry( |
| GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_PAGE, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, |
| referrer_chain.Get(1)); |
| EXPECT_TRUE(referrer_chain.Get(1).is_url_removed_by_policy()); |
| VerifyReferrerChainEntry( |
| GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| EXPECT_TRUE(referrer_chain.Get(2).is_url_removed_by_policy()); |
| VerifyReferrerChainEntry(GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::LANDING_REFERRER, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(3)); |
| EXPECT_TRUE(referrer_chain.Get(3).is_url_removed_by_policy()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| AllowlistDomainsRemoved_ServerRedirect) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| GURL request_url = |
| embedded_test_server()->GetURL("/server-redirect?" + download_url.spec()); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), request_url)); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| |
| // Add URLs to the Safe Browsing allowlist. |
| base::Value::List allowlist; |
| allowlist.Append(initial_url.host()); |
| allowlist.Append(download_url.host()); |
| allowlist.Append(request_url.host()); |
| browser()->profile()->GetPrefs()->SetList( |
| prefs::kSafeBrowsingAllowlistDomains, std::move(allowlist)); |
| |
| ReferrerChain referrer_chain; |
| IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); |
| ASSERT_EQ(1, referrer_chain.size()); |
| EXPECT_TRUE(referrer_chain.Get(0).is_url_removed_by_policy()); |
| // All URL fields should be empty because they all match the allowlist. |
| VerifyReferrerChainEntry(GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::EVENT_URL, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| {GURL(), GURL()}, // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(0)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| AllowlistDomainsRemoved_RecentNavigation) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("direct_download", 1, initial_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| |
| // Add URLs to the Safe Browsing allowlist. |
| base::Value::List allowlist; |
| allowlist.Append(initial_url.host()); |
| allowlist.Append(download_url.host()); |
| browser()->profile()->GetPrefs()->SetList( |
| prefs::kSafeBrowsingAllowlistDomains, std::move(allowlist)); |
| |
| ReferrerChain referrer_chain; |
| AppendRecentNavigations(/*recent_navigation_count=*/2, &referrer_chain); |
| EXPECT_EQ(2, referrer_chain.size()); |
| // All URL fields should be empty because they all match the allowlist. |
| VerifyReferrerChainEntry( |
| GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| EXPECT_TRUE(referrer_chain.Get(0).is_url_removed_by_policy()); |
| VerifyReferrerChainEntry(GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(1)); |
| EXPECT_TRUE(referrer_chain.Get(1).is_url_removed_by_policy()); |
| } |
| |
| // Test failure on macOS: crbug.com/1287901 |
| #if BUILDFLAG(IS_MAC) |
| #define MAYBE_AppendRecentNavigationsToEmptyReferrerChain \ |
| DISABLED_AppendRecentNavigationsToEmptyReferrerChain |
| #else |
| #define MAYBE_AppendRecentNavigationsToEmptyReferrerChain \ |
| AppendRecentNavigationsToEmptyReferrerChain |
| #endif |
| IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, |
| MAYBE_AppendRecentNavigationsToEmptyReferrerChain) { |
| ASSERT_TRUE(ui_test_utils::NavigateToURL( |
| browser(), embedded_test_server()->GetURL(kSingleFrameTestURL))); |
| GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); |
| ClickTestLink("complete_referrer_chain", 2, initial_url); |
| GURL redirect_url = embedded_test_server()->GetURL(kRedirectToLandingURL); |
| GURL landing_url = embedded_test_server()->GetURL(kLandingURL); |
| ClickTestLink("download_on_landing_page", 1, landing_url); |
| GURL download_url = embedded_test_server()->GetURL(kDownloadItemURL); |
| std::string test_server_ip(embedded_test_server()->host_port_pair().host()); |
| |
| ReferrerChain referrer_chain; |
| AppendRecentNavigations(/*recent_navigation_count=*/3, &referrer_chain); |
| EXPECT_EQ(4, referrer_chain.size()); |
| VerifyReferrerChainEntry( |
| download_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| landing_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(0)); |
| // This entry is empty, because it is omitted to make space for entries with |
| // user gesture. |
| VerifyReferrerChainEntry(GURL(), // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::CLIENT_REDIRECT, // type |
| "", // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::UNDEFINED, |
| referrer_chain.Get(1)); |
| // The is_url_removed_by_policy field should not be set on empty entry. |
| EXPECT_FALSE(referrer_chain.Get(1).has_is_url_removed_by_policy()); |
| VerifyReferrerChainEntry( |
| redirect_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| initial_url, // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE, |
| referrer_chain.Get(2)); |
| VerifyReferrerChainEntry(initial_url, // url |
| GURL(), // main_frame_url |
| ReferrerChainEntry::RECENT_NAVIGATION, // type |
| test_server_ip, // ip_address |
| GURL(), // referrer_url |
| GURL(), // referrer_main_frame_url |
| false, // is_retargeting |
| std::vector<GURL>(), // server redirects |
| ReferrerChainEntry::BROWSER_INITIATED, |
| referrer_chain.Get(3)); |
| } |
| |
| } // namespace safe_browsing |