Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H _ | 5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H _ |
| 6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H _ | 6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H _ |
| 7 | 7 |
| 8 #include "chrome/common/safe_browsing/csd.pb.h" | |
| 8 #include "content/public/browser/notification_observer.h" | 9 #include "content/public/browser/notification_observer.h" |
| 9 #include "content/public/browser/notification_registrar.h" | 10 #include "content/public/browser/notification_registrar.h" |
| 10 #include "content/public/browser/web_contents_observer.h" | 11 #include "content/public/browser/web_contents_observer.h" |
| 11 #include "url/gurl.h" | 12 #include "url/gurl.h" |
| 12 | 13 |
| 13 namespace safe_browsing { | 14 namespace safe_browsing { |
| 14 | 15 |
| 15 class SafeBrowsingNavigationObserver; | 16 class SafeBrowsingNavigationObserver; |
| 16 struct NavigationEvent; | 17 struct NavigationEvent; |
| 17 struct ResolvedIPAddress; | 18 struct ResolvedIPAddress; |
| 18 | 19 |
| 19 // Manager class for SafeBrowsingNavigationObserver, which is in charge of | 20 // Manager class for SafeBrowsingNavigationObserver, which is in charge of |
| 20 // cleaning up stale navigation events, and identifing landing page/landing | 21 // cleaning up stale navigation events, and identifying landing page/landing |
| 21 // referrer for a specific download. | 22 // referrer for a specific download. |
| 22 // TODO(jialiul): For now, SafeBrowsingNavigationObserverManager also listens to | 23 // TODO(jialiul): For now, SafeBrowsingNavigationObserverManager also listens to |
| 23 // NOTIFICATION_RETARGETING as a way to detect cross frame/tab navigation. | 24 // NOTIFICATION_RETARGETING as a way to detect cross frame/tab navigation. |
| 24 // Remove base class content::NotificationObserver when | 25 // Remove base class content::NotificationObserver when |
| 25 // WebContentsObserver::DidOpenRequestedURL() covers all retargeting cases. | 26 // WebContentsObserver::DidOpenRequestedURL() covers all retargeting cases. |
| 26 class SafeBrowsingNavigationObserverManager | 27 class SafeBrowsingNavigationObserverManager |
| 27 : public content::NotificationObserver, | 28 : public content::NotificationObserver, |
| 28 public base::RefCountedThreadSafe<SafeBrowsingNavigationObserverManager> { | 29 public base::RefCountedThreadSafe<SafeBrowsingNavigationObserverManager> { |
| 29 public: | 30 public: |
| 31 // For UMA histogram counting. Do NOT change order. | |
| 32 enum AttributionResult { | |
| 33 SUCCESS = 1, // Identified referrer chain is not empty. | |
| 34 SUCCESS_LANDING_PAGE = 2, // Successfully identified landing page. | |
| 35 SUCCESS_LANDING_REFERRER = 3, // Successfully identified landing referrer. | |
| 36 INVALID_URL = 4, | |
| 37 NAVIGATION_EVENT_NOT_FOUND = 5, | |
| 38 | |
| 39 // Always at the end | |
|
Charlie Reis
2016/12/09 22:00:25
nit: End with period.
Jialiu Lin
2016/12/12 23:43:38
Done.
| |
| 40 ATTRIBUTION_FAILURE_TYPE_MAX | |
| 41 }; | |
| 42 | |
| 30 // Helper function to check if user gesture is older than | 43 // Helper function to check if user gesture is older than |
| 31 // kUserGestureTTLInSecond. | 44 // kUserGestureTTLInSecond. |
| 32 static bool IsUserGestureExpired(const base::Time& timestamp); | 45 static bool IsUserGestureExpired(const base::Time& timestamp); |
| 33 // Helper function to strip empty ref fragment from a URL. Many pages | 46 // Helper function to strip empty ref fragment from a URL. Many pages |
| 34 // end up with a "#" at the end of their URLs due to navigation triggered by | 47 // end up with a "#" at the end of their URLs due to navigation triggered by |
| 35 // href="#" and javascript onclick function. We don't want to have separate | 48 // href="#" and javascript onclick function. We don't want to have separate |
| 36 // entries for these cases in the maps. | 49 // entries for these cases in the maps. |
| 37 static GURL ClearEmptyRef(const GURL& url); | 50 static GURL ClearEmptyRef(const GURL& url); |
| 38 | 51 |
| 39 SafeBrowsingNavigationObserverManager(); | 52 SafeBrowsingNavigationObserverManager(); |
| 40 | 53 |
| 41 // Add |nav_event| to |navigation_map_| based on |nav_event_key|. Object | 54 // Add |nav_event| to |navigation_map_| based on |nav_event_key|. Object |
| 42 // pointed to by |nav_event| will be no longer accessible after this function. | 55 // pointed to by |nav_event| will be no longer accessible after this function. |
| 43 void RecordNavigationEvent(const GURL& nav_event_key, | 56 void RecordNavigationEvent(const GURL& nav_event_key, |
| 44 NavigationEvent* nav_event); | 57 NavigationEvent* nav_event); |
| 45 void RecordUserGestureForWebContents(content::WebContents* web_contents, | 58 void RecordUserGestureForWebContents(content::WebContents* web_contents, |
| 46 const base::Time& timestamp); | 59 const base::Time& timestamp); |
| 47 void OnUserGestureConsumed(content::WebContents* web_contents, | 60 void OnUserGestureConsumed(content::WebContents* web_contents, |
| 48 const base::Time& timestamp); | 61 const base::Time& timestamp); |
| 49 void RecordHostToIpMapping(const std::string& host, const std::string& ip); | 62 void RecordHostToIpMapping(const std::string& host, const std::string& ip); |
| 50 // Clean-ups need to be done when a WebContents gets destroyed. | 63 // Clean-ups need to be done when a WebContents gets destroyed. |
| 51 void OnWebContentDestroyed(content::WebContents* web_contents); | 64 void OnWebContentDestroyed(content::WebContents* web_contents); |
| 52 | 65 // Remove all the observed NavigationEvents, user gestures, and resolved IP |
|
Charlie Reis
2016/12/09 22:00:25
nit: These will be easier to read with blank lines
Jialiu Lin
2016/12/12 23:43:38
Done.
| |
| 53 // TODO(jialiul): more functions are coming for managing navigation_map_. | 66 // addresses that are older than kNavigationFootprintTTLInSecond. |
| 67 void CleanUpStaleNavigationFootprints(); | |
| 68 // Identify referrer chain within user_gesture_count_limit user gestures. | |
|
Charlie Reis
2016/12/09 22:00:25
Can you elaborate on this comment? This is kind o
Jialiu Lin
2016/12/12 23:43:38
Done.
Charlie Reis
2016/12/14 07:43:57
Thanks! That helps a lot.
| |
| 69 AttributionResult IdentifyReferrerChain( | |
| 70 const GURL& target_url, | |
| 71 int target_tab_id, // -1 if tab id is not valid | |
| 72 int user_gesture_count_limit, | |
| 73 std::vector<ReferrerChainEntry>* referrer_chain); | |
| 74 // Identify and add referrer chain to ClientDownloadRequest proto. | |
|
Charlie Reis
2016/12/09 22:00:25
Is |request| an output parameter? Where is the pr
Jialiu Lin
2016/12/12 23:43:38
ClientDownloadRequest is located at chrome/common/
| |
| 75 // TODO(jialiul): This function will be moved to DownloadProtectionService | |
| 76 // class shortly. | |
| 77 void AddReferrerChainToClientDownloadRequest( | |
| 78 const GURL& download_url, | |
| 79 content::WebContents* source_contents, | |
| 80 ClientDownloadRequest* request); | |
| 54 | 81 |
| 55 private: | 82 private: |
| 56 friend class base::RefCountedThreadSafe< | 83 friend class base::RefCountedThreadSafe< |
| 57 SafeBrowsingNavigationObserverManager>; | 84 SafeBrowsingNavigationObserverManager>; |
| 58 friend class TestNavigationObserverManager; | 85 friend class TestNavigationObserverManager; |
| 59 friend class SBNavigationObserverBrowserTest; | 86 friend class SBNavigationObserverBrowserTest; |
| 60 friend class SBNavigationObserverTest; | 87 friend class SBNavigationObserverTest; |
| 88 FRIEND_TEST_ALL_PREFIXES(SBNavigationObserverTest, | |
|
Charlie Reis
2016/12/09 22:00:25
This is already listed as a friend class above. I
Jialiu Lin
2016/12/12 23:43:38
Done.
These tests called SafeBrowsingNavigationOb
| |
| 89 TestCleanUpStaleNavigationEvents); | |
| 90 FRIEND_TEST_ALL_PREFIXES(SBNavigationObserverTest, | |
| 91 TestCleanUpStaleUserGestures); | |
| 92 FRIEND_TEST_ALL_PREFIXES(SBNavigationObserverTest, | |
| 93 TestCleanUpStaleIPAddresses); | |
| 61 | 94 |
| 62 struct GurlHash { | 95 struct GurlHash { |
| 63 std::size_t operator()(const GURL& url) const { | 96 std::size_t operator()(const GURL& url) const { |
| 64 return std::hash<std::string>()(url.spec()); | 97 return std::hash<std::string>()(url.spec()); |
| 65 } | 98 } |
| 66 }; | 99 }; |
| 67 | 100 |
| 68 typedef std::unordered_map<GURL, std::vector<NavigationEvent>, GurlHash> | 101 typedef std::unordered_map<GURL, std::vector<NavigationEvent>, GurlHash> |
| 69 NavigationMap; | 102 NavigationMap; |
| 70 typedef std::unordered_map<content::WebContents*, base::Time> UserGestureMap; | 103 typedef std::unordered_map<content::WebContents*, base::Time> UserGestureMap; |
| 71 typedef std::unordered_map<std::string, std::vector<ResolvedIPAddress>> | 104 typedef std::unordered_map<std::string, std::vector<ResolvedIPAddress>> |
| 72 HostToIpMap; | 105 HostToIpMap; |
| 73 | 106 |
| 74 ~SafeBrowsingNavigationObserverManager() override; | 107 ~SafeBrowsingNavigationObserverManager() override; |
| 75 | 108 |
| 76 // content::NotificationObserver: | 109 // content::NotificationObserver: |
| 77 void Observe(int type, | 110 void Observe(int type, |
| 78 const content::NotificationSource& source, | 111 const content::NotificationSource& source, |
| 79 const content::NotificationDetails& details) override; | 112 const content::NotificationDetails& details) override; |
| 80 | 113 |
| 81 void RecordRetargeting(const content::NotificationDetails& details); | 114 void RecordRetargeting(const content::NotificationDetails& details); |
| 82 | 115 |
| 83 NavigationMap* navigation_map() { return &navigation_map_; } | 116 NavigationMap* navigation_map() { return &navigation_map_; } |
| 84 | 117 |
| 85 HostToIpMap* host_to_ip_map() { return &host_to_ip_map_; } | 118 HostToIpMap* host_to_ip_map() { return &host_to_ip_map_; } |
| 86 | 119 |
| 120 // Remove stale entries from navigation_map_ if they are older than | |
| 121 // kNavigationFootprintTTLInSecond (2 minutes). | |
| 122 void CleanUpNavigationEvents(); | |
| 123 | |
| 124 // Remove stale entries from user_gesture_map_ if they are older than | |
| 125 // kUserGestureTTLInSecond (1 sec). | |
| 126 void CleanUpUserGestures(); | |
| 127 | |
| 128 // Remove stale entries from host_to_ip_map_ if they are older than | |
| 129 // kNavigationFootprintTTLInSecond (2 minutes). | |
| 130 void CleanUpIpAddresses(); | |
| 131 | |
| 132 bool IsCleanUpScheduled() const; | |
| 133 | |
| 134 void ScheduleNextCleanUpAfterInterval(base::TimeDelta interval); | |
| 135 | |
| 136 NavigationEvent* FindNavigationEvent(const GURL& target_url, | |
| 137 int target_tab_id); | |
| 138 void AddToReferrerChain( | |
| 139 std::vector<ReferrerChainEntry>* | |
| 140 referrer_chain, | |
| 141 NavigationEvent* nav_event, | |
| 142 ReferrerChainEntry::URLType type); | |
| 143 | |
| 87 // navigation_map_ keeps track of all the observed navigations. This map is | 144 // navigation_map_ keeps track of all the observed navigations. This map is |
| 88 // keyed on the resolved request url. In other words, in case of server | 145 // keyed on the resolved request url. In other words, in case of server |
| 89 // redirects, its key is the last server redirect url, otherwise, it is the | 146 // redirects, its key is the last server redirect url, otherwise, it is the |
| 90 // original target url. Since the same url can be requested multiple times | 147 // original target url. Since the same url can be requested multiple times |
| 91 // across different tabs and frames, the value of this map is a vector of | 148 // across different tabs and frames, the value of this map is a vector of |
| 92 // NavigationEvent ordered by navigation finish time. | 149 // NavigationEvent ordered by navigation finish time. |
| 93 // TODO(jialiul): Entries in navigation_map_ will be removed if they are older | 150 // TODO(jialiul): Entries in navigation_map_ will be removed if they are older |
| 94 // than 2 minutes since their corresponding navigations finish. | 151 // than 2 minutes since their corresponding navigations finish. |
| 95 NavigationMap navigation_map_; | 152 NavigationMap navigation_map_; |
| 96 | 153 |
| 97 // user_gesture_map_ keeps track of the timestamp of last user gesture in | 154 // user_gesture_map_ keeps track of the timestamp of last user gesture in |
| 98 // in each WebContents. We assume for majority of cases, a navigation | 155 // in each WebContents. We assume for majority of cases, a navigation |
| 99 // shortly after a user gesture indicate this navigation is user initiated. | 156 // shortly after a user gesture indicate this navigation is user initiated. |
| 100 UserGestureMap user_gesture_map_; | 157 UserGestureMap user_gesture_map_; |
| 101 | 158 |
| 102 // Host to timestamped IP addresses map that covers all the main frame and | 159 // Host to timestamped IP addresses map that covers all the main frame and |
| 103 // subframe URLs' hosts. Since it is possible for a host to resolve to more | 160 // subframe URLs' hosts. Since it is possible for a host to resolve to more |
| 104 // than one IP in even a short period of time, we map a single host to a | 161 // than one IP in even a short period of time, we map a single host to a |
| 105 // vector of ResolvedIPAddresss. This map is used to fill in ip_address field | 162 // vector of ResolvedIPAddresss. This map is used to fill in ip_address field |
| 106 // in URLChainEntry in ClientDownloadRequest. | 163 // in URLChainEntry in ClientDownloadRequest. |
| 107 HostToIpMap host_to_ip_map_; | 164 HostToIpMap host_to_ip_map_; |
| 108 | 165 |
| 109 content::NotificationRegistrar registrar_; | 166 content::NotificationRegistrar registrar_; |
| 110 | 167 |
| 168 base::OneShotTimer cleanup_timer_; | |
| 169 | |
| 111 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingNavigationObserverManager); | 170 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingNavigationObserverManager); |
| 112 }; | 171 }; |
| 113 } // namespace safe_browsing | 172 } // namespace safe_browsing |
| 114 | 173 |
| 115 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGE R_H_ | 174 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGE R_H_ |
| OLD | NEW |