1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
7 
8 #include "base/scoped_observer.h"
9 #include "base/supports_user_data.h"
10 #include "components/content_settings/core/browser/content_settings_observer.h"
11 #include "components/content_settings/core/browser/host_content_settings_map.h"
12 #include "components/content_settings/core/common/content_settings.h"
13 #include "components/safe_browsing/core/proto/csd.pb.h"
14 #include "components/sessions/core/session_id.h"
15 #include "content/public/browser/web_contents_observer.h"
16 #include "url/gurl.h"
17 
18 namespace content {
19 class NavigationHandle;
20 }
21 
22 namespace safe_browsing {
23 class SafeBrowsingNavigationObserverManager;
24 
25 // Struct to record the details of a navigation event for any frame.
26 // This information will be used to fill referrer chain info in various Safe
27 // Browsing requests and reports.
28 struct NavigationEvent {
29   NavigationEvent();
30   NavigationEvent(NavigationEvent&& nav_event);
31   NavigationEvent& operator=(NavigationEvent&& nav_event);
32   ~NavigationEvent();
33 
34   // URL that caused this navigation to occur.
35   GURL source_url;
36 
37   // Main frame url of the source_url. Could be the same as source_url, if
38   // source_url was loaded in main frame.
39   GURL source_main_frame_url;
40 
41   // The original request URL of this navigation.
42   GURL original_request_url;
43 
44   // Server redirect url chain. Empty if there is no server redirect. If set,
45   // last url in this vector is the destination url.
46   std::vector<GURL> server_redirect_urls;
47 
48   // Which tab contains the frame with source_url. Tab ID is returned by
49   // sessions::SessionTabHelper::IdForTab. This ID is immutable for a given tab
50   // and unique across Chrome within the current session.
51   SessionID source_tab_id;
52 
53   // Which tab this request url is targeting to.
54   SessionID target_tab_id;
55 
56   // Frame tree node ID of the frame where this navigation takes place.
57   int frame_id;
58 
59   // When this NavigationEvent was last updated.
60   base::Time last_updated;
61 
62   // If this navigation is triggered by browser or renderer, and if it is
63   // associated with any user gesture.
64   ReferrerChainEntry::NavigationInitiation navigation_initiation;
65 
66   // Whether this a committed navigation. Navigation leads to download is not
67   // committed.
68   bool has_committed;
69 
70   // Whether we think this event was launched by an external application.
71   bool maybe_launched_by_external_application;
72 
GetDestinationUrlNavigationEvent73   const GURL& GetDestinationUrl() const {
74     if (!server_redirect_urls.empty())
75       return server_redirect_urls.back();
76     else
77       return original_request_url;
78   }
79 
IsUserInitiatedNavigationEvent80   bool IsUserInitiated() const {
81     return navigation_initiation == ReferrerChainEntry::BROWSER_INITIATED ||
82            navigation_initiation ==
83                ReferrerChainEntry::RENDERER_INITIATED_WITH_USER_GESTURE;
84   }
85 };
86 
87 // Structure to keep track of resolved IP address of a host.
88 struct ResolvedIPAddress {
ResolvedIPAddressResolvedIPAddress89   ResolvedIPAddress() : timestamp(base::Time::Now()), ip() {}
ResolvedIPAddressResolvedIPAddress90   ResolvedIPAddress(base::Time timestamp, const std::string& ip)
91       : timestamp(timestamp), ip(ip) {}
92   base::Time timestamp;  // Timestamp of when we get the resolved IP.
93   std::string ip;        // Resolved IP address
94 };
95 
96 // Observes the navigation events for a single WebContents (both main-frame
97 // and sub-frame navigations).
98 class SafeBrowsingNavigationObserver : public base::SupportsUserData::Data,
99                                        public content::WebContentsObserver,
100                                        public content_settings::Observer {
101  public:
102   static void MaybeCreateForWebContents(
103       content::WebContents* web_contents);
104 
105   static SafeBrowsingNavigationObserver* FromWebContents(
106       content::WebContents* web_contents);
107 
108   SafeBrowsingNavigationObserver(
109       content::WebContents* contents,
110       const scoped_refptr<SafeBrowsingNavigationObserverManager>& manager);
111 
112   ~SafeBrowsingNavigationObserver() override;
113 
114  private:
115   FRIEND_TEST_ALL_PREFIXES(SBNavigationObserverTest, TestContentSettingChange);
116   typedef std::unordered_map<content::NavigationHandle*,
117                              std::unique_ptr<NavigationEvent>>
118       NavigationHandleMap;
119 
120   void OnUserInteraction();
121 
122   // content::WebContentsObserver:
123   void DidStartNavigation(
124       content::NavigationHandle* navigation_handle) override;
125   void DidRedirectNavigation(
126       content::NavigationHandle* navigation_handle) override;
127   void DidFinishNavigation(
128       content::NavigationHandle* navigation_handle) override;
129   void DidGetUserInteraction(const blink::WebInputEvent& event) override;
130   void WebContentsDestroyed() override;
131   void DidOpenRequestedURL(content::WebContents* new_contents,
132                            content::RenderFrameHost* source_render_frame_host,
133                            const GURL& url,
134                            const content::Referrer& referrer,
135                            WindowOpenDisposition disposition,
136                            ui::PageTransition transition,
137                            bool started_from_context_menu,
138                            bool renderer_initiated) override;
139 
140   // content_settings::Observer overrides.
141   void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
142                                const ContentSettingsPattern& secondary_pattern,
143                                ContentSettingsType content_type) override;
144 
145   // Map keyed on NavigationHandle* to keep track of all the ongoing navigation
146   // events. NavigationHandle pointers are owned by RenderFrameHost. Since a
147   // NavigationHandle object will be destructed after navigation is done,
148   // at the end of DidFinishNavigation(...) corresponding entries in this map
149   // will be removed from navigation_handle_map_ and added to
150   // SafeBrowsingNavigationObserverManager::navigation_map_.
151   NavigationHandleMap navigation_handle_map_;
152 
153   scoped_refptr<SafeBrowsingNavigationObserverManager> manager_;
154 
155   ScopedObserver<HostContentSettingsMap, content_settings::Observer>
156       content_settings_observer_{this};
157 
158   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingNavigationObserver);
159 };
160 
161 }  // namespace safe_browsing
162 
163 #endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
164