1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_BLOCKED_CONTENT_SAFE_BROWSING_TRIGGERED_POPUP_BLOCKER_H_
#define COMPONENTS_BLOCKED_CONTENT_SAFE_BROWSING_TRIGGERED_POPUP_BLOCKER_H_
#include <optional>
#include "base/feature_list.h"
#include "base/gtest_prod_util.h"
#include "base/scoped_observation.h"
#include "components/safe_browsing/core/browser/db/util.h"
#include "components/subresource_filter/content/browser/subresource_filter_observer.h"
#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
#include "content/public/browser/navigation_handle_user_data.h"
#include "content/public/browser/page_user_data.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
class WebContents;
} // namespace content
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace blocked_content {
BASE_DECLARE_FEATURE(kAbusiveExperienceEnforce);
constexpr char kAbusiveEnforceMessage[] =
"Chrome prevented this site from opening a new tab or window. Learn more "
"at https://www.chromestatus.com/feature/5243055179300864";
constexpr char kAbusiveWarnMessage[] =
"Chrome might start preventing this site from opening new tabs or "
"windows in the future. Learn more at "
"https://www.chromestatus.com/feature/5243055179300864";
// This class observes main frame navigation checks incoming from safe browsing
// (currently implemented by the subresource_filter component). For navigations
// which match the ABUSIVE safe browsing list, this class will help the popup
// tab helper in applying a stronger policy for blocked popups.
class SafeBrowsingTriggeredPopupBlocker
: public content::WebContentsObserver,
public content::WebContentsUserData<SafeBrowsingTriggeredPopupBlocker>,
public subresource_filter::SubresourceFilterObserver {
public:
// This enum backs a histogram. Please append new entries to the end, and
// update enums.xml when making changes.
enum class Action : int {
// User committed a navigation to a non-error page.
kNavigation,
// Safe Browsing considered this page abusive and the page should be warned.
// Logged at navigation commit.
kWarningSite,
// Safe Browsing considered this page abusive and the page should be be
// blocked against. Logged at navigation commit.
kEnforcedSite,
// The popup blocker called into this object to ask if the strong blocking
// should be applied.
kConsidered,
// This object responded to the popup blocker in the affirmative, and the
// popup was blocked.
kBlocked,
// Add new entries before this one
kCount
};
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Creates a SafeBrowsingTriggeredPopupBlocker and attaches it (via UserData)
// to |web_contents|.
static void MaybeCreate(content::WebContents* web_contents);
SafeBrowsingTriggeredPopupBlocker(const SafeBrowsingTriggeredPopupBlocker&) =
delete;
SafeBrowsingTriggeredPopupBlocker& operator=(
const SafeBrowsingTriggeredPopupBlocker&) = delete;
~SafeBrowsingTriggeredPopupBlocker() override;
bool ShouldApplyAbusivePopupBlocker(content::Page& page);
private:
FRIEND_TEST_ALL_PREFIXES(SafeBrowsingTriggeredPopupBlockerTest,
NonPrimaryFrameTree);
friend class content::WebContentsUserData<SafeBrowsingTriggeredPopupBlocker>;
// The |web_contents| and |observer_manager| are expected to be
// non-nullptr.
SafeBrowsingTriggeredPopupBlocker(
content::WebContents* web_contents,
subresource_filter::SubresourceFilterObserverManager* observer_manager);
// content::WebContentsObserver:
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
// subresource_filter::SubresourceFilterObserver:
void OnSafeBrowsingChecksComplete(
content::NavigationHandle* navigation_handle,
const subresource_filter::SubresourceFilterSafeBrowsingClient::
CheckResult& result) override;
void OnSubresourceFilterGoingAway() override;
// Enabled state is governed by both a feature flag and a pref (which can be
// controlled by enterprise policy).
static bool IsEnabled(content::WebContents* web_contents);
// Data scoped to a single page. PageData has the same lifetime as the page's
// main document.
class PageData : public content::PageUserData<PageData> {
public:
explicit PageData(content::Page& page);
PageData(const PageData&) = delete;
PageData& operator=(const PageData&) = delete;
// Logs UMA in the destructor based on the number of popups blocked.
~PageData() override;
void inc_num_popups_blocked() { ++num_popups_blocked_; }
void set_is_triggered(bool is_triggered) { is_triggered_ = is_triggered; }
bool is_triggered() const { return is_triggered_; }
PAGE_USER_DATA_KEY_DECL();
private:
// How many popups are blocked in this page.
int num_popups_blocked_ = 0;
// Whether the current committed page load should trigger the stronger popup
// blocker.
bool is_triggered_ = false;
};
class NavigationHandleData
: public content::NavigationHandleUserData<NavigationHandleData> {
public:
explicit NavigationHandleData(content::NavigationHandle&);
~NavigationHandleData() override;
std::optional<safe_browsing::SubresourceFilterLevel>&
level_for_next_committed_navigation() {
return level_for_next_committed_navigation_;
}
NAVIGATION_HANDLE_USER_DATA_KEY_DECL();
private:
// Whether this navigation should trigger the stronger popup blocker in
// enforce or warn mode.
std::optional<safe_browsing::SubresourceFilterLevel>
level_for_next_committed_navigation_;
};
// Returns the PageData for the specified |page|.
PageData& GetPageData(content::Page& page);
base::ScopedObservation<subresource_filter::SubresourceFilterObserverManager,
subresource_filter::SubresourceFilterObserver>
scoped_observation_{this};
WEB_CONTENTS_USER_DATA_KEY_DECL();
};
} // namespace blocked_content
#endif // COMPONENTS_BLOCKED_CONTENT_SAFE_BROWSING_TRIGGERED_POPUP_BLOCKER_H_
|