File: safe_browsing_navigation_observer.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 (210 lines) | stat: -rw-r--r-- 8,453 bytes parent folder | download | duplicates (10)
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// 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.

#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_H_

#include <unordered_map>

#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/supports_user_data.h"
#include "base/time/time.h"
#include "components/content_settings/core/browser/content_settings_observer.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/safe_browsing/core/common/proto/csd.pb.h"
#include "components/sessions/core/session_id.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents_observer.h"
#include "url/gurl.h"

namespace content {
class NavigationHandle;
}

namespace safe_browsing {
class SafeBrowsingNavigationObserverManager;

// Struct to record the details of a navigation event for any frame.
// This information will be used to fill referrer chain info in various Safe
// Browsing requests and reports.
struct NavigationEvent {
  NavigationEvent();
  NavigationEvent(NavigationEvent&& nav_event);
  NavigationEvent(const NavigationEvent& nav_event);
  NavigationEvent& operator=(NavigationEvent&& nav_event);
  ~NavigationEvent();

  // URL that caused this navigation to occur.
  GURL source_url;

  // Main frame url of the source_url. Could be the same as source_url, if
  // source_url was loaded in main frame.
  GURL source_main_frame_url;

  // The original request URL of this navigation.
  GURL original_request_url;

  // Server redirect url chain. Empty if there is no server redirect. If set,
  // last url in this vector is the destination url.
  std::vector<GURL> server_redirect_urls;

  // Which tab contains the frame with source_url. Tab ID is returned by
  // sessions::SessionTabHelper::IdForTab. This ID is immutable for a given tab
  // and unique across Chrome within the current session.
  SessionID source_tab_id;

  // Which tab this request url is targeting to.
  SessionID target_tab_id;

  // RFH ID of the outermost main frame of the frame which initiated this
  // navigation. This can only differ from outermost_main_frame_id if
  // |is_outermost_main_frame| is true, however differing values does not imply
  // that we're in the outermost main frame (we could be navigating within the
  // current RFH).
  content::GlobalRenderFrameHostId initiator_outermost_main_frame_id;

  // RFH ID of the outermost main frame of the frame where this navigation takes
  // place. If this navigation is occurring in the outermost main frame, then
  // this is not known until commit.
  content::GlobalRenderFrameHostId outermost_main_frame_id;

  // Whether this navigation is happening in the outermost main frame.
  bool is_outermost_main_frame = false;

  // When this NavigationEvent was last updated.
  base::Time last_updated;

  // If this navigation is triggered by browser or renderer, and if it is
  // associated with any user gesture.
  ReferrerChainEntry::NavigationInitiation navigation_initiation;

  // Whether this a committed navigation. Navigation leads to download is not
  // committed.
  bool has_committed;

  // Whether we think this event was launched by an external application.
  bool maybe_launched_by_external_application;

  const GURL& GetDestinationUrl() const {
    if (!server_redirect_urls.empty())
      return server_redirect_urls.back();
    else
      return original_request_url;
  }

  bool IsUserInitiated() const {
    return navigation_initiation == ReferrerChainEntry::BROWSER_INITIATED ||
           navigation_initiation ==
               ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE;
  }
};

// Structure to keep track of resolved IP address of a host.
struct ResolvedIPAddress {
  ResolvedIPAddress() : timestamp(base::Time::Now()), ip() {}
  ResolvedIPAddress(base::Time timestamp, const std::string& ip)
      : timestamp(timestamp), ip(ip) {}
  base::Time timestamp;  // Timestamp of when we get the resolved IP.
  std::string ip;        // Resolved IP address
};

// Observes the navigation events for a single WebContents (both main-frame
// and sub-frame navigations).
class SafeBrowsingNavigationObserver : public base::SupportsUserData::Data,
                                       public content::WebContentsObserver,
                                       public content_settings::Observer {
 public:
  static void MaybeCreateForWebContents(
      content::WebContents* web_contents,
      HostContentSettingsMap* host_content_settings_map,
      SafeBrowsingNavigationObserverManager* observer_manager,
      PrefService* prefs,
      bool has_safe_browsing_service);

  static SafeBrowsingNavigationObserver* FromWebContents(
      content::WebContents* web_contents);

  SafeBrowsingNavigationObserver(
      content::WebContents* contents,
      HostContentSettingsMap* host_content_settings_map,
      SafeBrowsingNavigationObserverManager* observer_manager);

  SafeBrowsingNavigationObserver(const SafeBrowsingNavigationObserver&) =
      delete;
  SafeBrowsingNavigationObserver& operator=(
      const SafeBrowsingNavigationObserver&) = delete;

  ~SafeBrowsingNavigationObserver() override;

  void SetObserverManagerForTesting(
      SafeBrowsingNavigationObserverManager* observer_manager);

 private:
  FRIEND_TEST_ALL_PREFIXES(SBNavigationObserverTest, TestContentSettingChange);
  typedef std::unordered_map<content::NavigationHandle*,
                             std::unique_ptr<NavigationEvent>>
      NavigationHandleMap;

  void OnUserInteraction();

  SafeBrowsingNavigationObserverManager* GetObserverManager();

  // content::WebContentsObserver:
  void DidStartNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidRedirectNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidGetUserInteraction(const blink::WebInputEvent& event) override;
  void WebContentsDestroyed() override;
  void DidOpenRequestedURL(content::WebContents* new_contents,
                           content::RenderFrameHost* source_render_frame_host,
                           const GURL& url,
                           const content::Referrer& referrer,
                           WindowOpenDisposition disposition,
                           ui::PageTransition transition,
                           bool started_from_context_menu,
                           bool renderer_initiated) override;

  // content_settings::Observer overrides.
  void OnContentSettingChanged(
      const ContentSettingsPattern& primary_pattern,
      const ContentSettingsPattern& secondary_pattern,
      ContentSettingsTypeSet content_type_set) override;

  // Setter functions for fields in |nav_event|.
  void SetNavigationInitiationAndRecordUserGesture(
      content::NavigationHandle* navigation_handle,
      NavigationEvent* nav_event);
  void SetNavigationSourceUrl(content::NavigationHandle* navigation_handle,
                              NavigationEvent* nav_event);
  void SetNavigationSourceMainFrameUrl(
      content::NavigationHandle* navigation_handle,
      NavigationEvent* nav_event);
  void SetNavigationOutermostMainFrameIds(
      content::NavigationHandle* navigation_handle,
      NavigationEvent* nav_event);

  // Map keyed on NavigationHandle* to keep track of all the ongoing
  // navigation events. NavigationHandle pointers are owned by
  // RenderFrameHost. Since a NavigationHandle object will be destructed
  // after navigation is done, at the end of DidFinishNavigation(...)
  // corresponding entries in this map will be removed from
  // navigation_handle_map_ and added to
  // SafeBrowsingNavigationObserverManager::navigation_map_.
  NavigationHandleMap navigation_handle_map_;

  base::ScopedObservation<HostContentSettingsMap, content_settings::Observer>
      content_settings_observation_{this};

  raw_ptr<SafeBrowsingNavigationObserverManager> observer_manager_ = nullptr;
};

}  // namespace safe_browsing

#endif  // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_H_