File: safe_browsing_triggered_popup_blocker.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (174 lines) | stat: -rw-r--r-- 6,339 bytes parent folder | download | duplicates (8)
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_