Skip to content

Commit

Permalink
SB: Modify referrer for copy paste navigation
Browse files Browse the repository at this point in the history
When creating the referrer chain:
- if the referrer is empty
- the URL was the last copied URL to the clipboard

Fill out the referrer and main-frame referrer
with the frame and page where the copies were
created.

Bug: 754330

Change-Id: Iaaeb42d27ce8ee02f764fe728f7a100204dfd95e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4528803
Reviewed-by: Xinghui Lu <xinghuilu@chromium.org>
Reviewed-by: Daniel Rubery <drubery@chromium.org>
Commit-Queue: Kristian Monsen <kristianm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1150757}
  • Loading branch information
kristianmonsen authored and Chromium LUCI CQ committed May 30, 2023
1 parent 10a17e7 commit e10e236
Show file tree
Hide file tree
Showing 8 changed files with 476 additions and 7 deletions.

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions chrome/test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -10553,6 +10553,10 @@ if (!is_android) {
# For support version skew testing.
data_deps += [ "//build:version_metadata" ]
}

if (safe_browsing_mode == 1) {
sources += [ "../browser/safe_browsing/safe_browsing_navigation_observer_interactive_test.cc" ]
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<body>
<iframe id="iframe" src="copy_referrer_inner.html"></iframe>
Main page contents

<script>
// The iframe needs to be focused to let the JS from test copy to
// clipboard.
document.getElementById('iframe').focus();
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body>
Iframe contents
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "crypto/sha2.h"
#include "ui/base/clipboard/clipboard.h"

using content::WebContents;

Expand Down Expand Up @@ -278,12 +279,31 @@ size_t NavigationEventList::FindRetargetingNavigationEvent(
}

void NavigationEventList::RecordNavigationEvent(
std::unique_ptr<NavigationEvent> nav_event) {
std::unique_ptr<NavigationEvent> nav_event,
absl::optional<CopyPasteEntry> last_copy_paste_entry) {
// Skip page refresh and in-page navigation.
if (nav_event->source_url == nav_event->GetDestinationUrl() &&
nav_event->source_tab_id == nav_event->target_tab_id)
return;

// If the nav entry is without referrer, BROWSER_INITIATED
// and there is a recent copy, guess this is a paste to
// omnibox and modify nav event. This enables attribution
// in referrer chain.
if (nav_event->navigation_initiation ==
ReferrerChainEntry::BROWSER_INITIATED &&
nav_event->source_url.is_empty() &&
nav_event->source_main_frame_url.is_empty() &&
last_copy_paste_entry.has_value() &&
nav_event->original_request_url ==
last_copy_paste_entry.value().target_) {
nav_event->navigation_initiation =
ReferrerChainEntry::COPY_PASTE_USER_INITIATED;
nav_event->source_url = last_copy_paste_entry.value().source_frame_url_;
nav_event->source_main_frame_url =
last_copy_paste_entry.value().source_main_frame_url_;
}

if (navigation_events_.size() == size_limit_)
navigation_events_.pop_front();
navigation_events_.push_back(std::move(nav_event));
Expand Down Expand Up @@ -336,6 +356,18 @@ std::size_t NavigationEventList::CleanUpNavigationEvents() {
return removal_count;
}

// -------------------------CopyPasteEntry---------------------
CopyPasteEntry::CopyPasteEntry(GURL target,
GURL source_frame_url,
GURL source_main_frame_url,
base::Time recorded_time)
: target_(target),
source_frame_url_(source_frame_url),
source_main_frame_url_(source_main_frame_url),
recorded_time_(recorded_time) {}

CopyPasteEntry::CopyPasteEntry(const CopyPasteEntry& other) = default;

// -----------------SafeBrowsingNavigationObserverManager-----------
// static
bool SafeBrowsingNavigationObserverManager::IsUserGestureExpired(
Expand Down Expand Up @@ -399,6 +431,7 @@ SafeBrowsingNavigationObserverManager::SafeBrowsingNavigationObserverManager(
PrefService* pref_service)
: navigation_event_list_(GetNavigationRecordMaxSize()),
pref_service_(pref_service) {
ui::Clipboard::GetForCurrentThread()->AddObserver(this);
// Schedule clean up in 2 minutes.
ScheduleNextCleanUpAfterInterval(GetNavigationFootprintTTL());
}
Expand All @@ -407,7 +440,8 @@ void SafeBrowsingNavigationObserverManager::RecordNavigationEvent(
content::NavigationHandle* navigation_handle,
std::unique_ptr<NavigationEvent> nav_event) {
navigation_event_list_.RemovePendingNavigationEvent(navigation_handle);
navigation_event_list_.RecordNavigationEvent(std::move(nav_event));
navigation_event_list_.RecordNavigationEvent(std::move(nav_event),
last_copy_paste_entry_);
}

void SafeBrowsingNavigationObserverManager::RecordPendingNavigationEvent(
Expand Down Expand Up @@ -488,6 +522,7 @@ void SafeBrowsingNavigationObserverManager::CleanUpStaleNavigationFootprints() {
CleanUpNavigationEvents();
CleanUpUserGestures();
CleanUpIpAddresses();
CleanUpCopyData();
ScheduleNextCleanUpAfterInterval(GetNavigationFootprintTTL());
}

Expand Down Expand Up @@ -629,7 +664,9 @@ SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByHostingPage(
}

SafeBrowsingNavigationObserverManager::
~SafeBrowsingNavigationObserverManager() {}
~SafeBrowsingNavigationObserverManager() {
ui::Clipboard::GetForCurrentThread()->RemoveObserver(this);
}

void SafeBrowsingNavigationObserverManager::RecordNewWebContents(
content::WebContents* source_web_contents,
Expand Down Expand Up @@ -694,7 +731,8 @@ void SafeBrowsingNavigationObserverManager::RecordNewWebContents(
ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE;
}

navigation_event_list_.RecordNavigationEvent(std::move(nav_event));
navigation_event_list_.RecordNavigationEvent(std::move(nav_event),
last_copy_paste_entry_);
}

// static
Expand Down Expand Up @@ -754,6 +792,17 @@ void SafeBrowsingNavigationObserverManager::AppendRecentNavigations(
RemoveSafeBrowsingAllowlistDomains(out_referrer_chain);
}

void SafeBrowsingNavigationObserverManager::OnCopyURL(
const GURL& url,
const GURL& source_frame_url,
const GURL& source_main_frame_url) {
if (base::FeatureList::IsEnabled(
kSafeBrowsingReferrerChainWithCopyPasteNavigation)) {
last_copy_paste_entry_.emplace(url, source_frame_url, source_main_frame_url,
base::Time::Now());
}
}

void SafeBrowsingNavigationObserverManager::CleanUpNavigationEvents() {
navigation_event_list_.CleanUpNavigationEvents();
}
Expand All @@ -780,6 +829,15 @@ void SafeBrowsingNavigationObserverManager::CleanUpIpAddresses() {
}
}

void SafeBrowsingNavigationObserverManager::CleanUpCopyData() {
if (last_copy_paste_entry_.has_value()) {
if (IsEventExpired(last_copy_paste_entry_.value().recorded_time_,
GetNavigationFootprintTTL())) {
last_copy_paste_entry_ = absl::nullopt;
}
}
}

bool SafeBrowsingNavigationObserverManager::IsCleanUpScheduled() const {
return cleanup_timer_.IsRunning();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "content/public/browser/web_contents_observer.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/protobuf/src/google/protobuf/repeated_field.h"
#include "ui/base/clipboard/clipboard.h"
#include "url/gurl.h"

class PrefService;
Expand Down Expand Up @@ -63,6 +64,20 @@ class ReferrerChainData : public base::SupportsUserData::Data {
size_t recent_navigations_to_collect_;
};

// Struct to store a URL copied to the clipboard, along with which frame and
// main_frame this was copied from.
struct CopyPasteEntry {
explicit CopyPasteEntry(GURL target,
GURL source_frame_url,
GURL source_main_frame_url,
base::Time recorded_time);
CopyPasteEntry(const CopyPasteEntry& other);
GURL target_;
GURL source_frame_url_;
GURL source_main_frame_url_;
base::Time recorded_time_;
};

// Struct that manages insertion, cleanup, and lookup of NavigationEvent
// objects. Its maximum size is `GetNavigationRecordMaxSize()`.
struct NavigationEventList {
Expand Down Expand Up @@ -122,7 +137,9 @@ struct NavigationEventList {
SessionID target_tab_id,
size_t start_index);

void RecordNavigationEvent(std::unique_ptr<NavigationEvent> nav_event);
void RecordNavigationEvent(
std::unique_ptr<NavigationEvent> nav_event,
absl::optional<CopyPasteEntry> last_copy_paste_entry = absl::nullopt);

void RecordPendingNavigationEvent(
content::NavigationHandle* navigation_handle,
Expand Down Expand Up @@ -171,8 +188,10 @@ struct NavigationEventList {
// Manager class for SafeBrowsingNavigationObserver, which is in charge of
// cleaning up stale navigation events, and identifying landing page/landing
// referrer for a specific Safe Browsing event.
class SafeBrowsingNavigationObserverManager : public ReferrerChainProvider,
public KeyedService {
class SafeBrowsingNavigationObserverManager
: public ReferrerChainProvider,
public KeyedService,
public ui::Clipboard::ClipboardWriteObserver {
public:
// Helper function to check if user gesture is older than
// kUserGestureTTL.
Expand Down Expand Up @@ -304,6 +323,12 @@ class SafeBrowsingNavigationObserverManager : public ReferrerChainProvider,
void AppendRecentNavigations(size_t recent_navigation_count,
ReferrerChain* out_referrer_chain);

// ui::Clipboard::ClipboardWriteObserver:
// Event for new URLs copied to the clipboard
void OnCopyURL(const GURL& url,
const GURL& source_frame_url,
const GURL& source_main_frame_url) override;

protected:
NavigationEventList* navigation_event_list() {
return &navigation_event_list_;
Expand Down Expand Up @@ -339,6 +364,9 @@ class SafeBrowsingNavigationObserverManager : public ReferrerChainProvider,
// `GetNavigationFootprintTTL()`.
void CleanUpIpAddresses();

// Remove stale copy entries.
void CleanUpCopyData();

bool IsCleanUpScheduled() const;

void ScheduleNextCleanUpAfterInterval(base::TimeDelta interval);
Expand Down Expand Up @@ -401,6 +429,8 @@ class SafeBrowsingNavigationObserverManager : public ReferrerChainProvider,
raw_ptr<PrefService> pref_service_;

base::OneShotTimer cleanup_timer_;

absl::optional<CopyPasteEntry> last_copy_paste_entry_;
};
} // namespace safe_browsing

Expand Down
4 changes: 4 additions & 0 deletions components/safe_browsing/core/common/features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ BASE_FEATURE(kSafeBrowsingOnUIThread,
"SafeBrowsingOnUIThread",
base::FEATURE_DISABLED_BY_DEFAULT);

BASE_FEATURE(kSafeBrowsingReferrerChainWithCopyPasteNavigation,
"SafeBrowsingReferrerChainWithCopyPasteNavigation",
base::FEATURE_ENABLED_BY_DEFAULT);

BASE_FEATURE(kSafeBrowsingRemoveCookiesInAuthRequests,
"SafeBrowsingRemoveCookiesInAuthRequests",
base::FEATURE_DISABLED_BY_DEFAULT);
Expand Down
3 changes: 3 additions & 0 deletions components/safe_browsing/core/common/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ extern const base::FeatureParam<bool>
// Run Safe Browsing code on UI thread.
BASE_DECLARE_FEATURE(kSafeBrowsingOnUIThread);

// Enable adding copy/paste navigation to the referrer chain.
BASE_DECLARE_FEATURE(kSafeBrowsingReferrerChainWithCopyPasteNavigation);

// Controls whether cookies are removed when the access token is present.
BASE_DECLARE_FEATURE(kSafeBrowsingRemoveCookiesInAuthRequests);

Expand Down

0 comments on commit e10e236

Please sign in to comment.