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