15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class which handles communication with the SafeBrowsing backends for 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// client-side phishing detection. This class is used to fetch the client-side 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// model and send it to all renderers. This class is also used to send a ping 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back to Google to verify if a particular site is really phishing or not. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is not thread-safe and expects all calls to be made on the UI 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread. We also expect that the calling thread runs a message loop. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_ 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <queue> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SafeBrowsingService; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeDelta; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderProcessHost; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLFetcher; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestContextGetter; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestStatus; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<std::string> ResponseCookies; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace safe_browsing { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ClientMalwareRequest; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientPhishingRequest; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientPhishingResponse; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSideModel; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSideDetectionService : public net::URLFetcherDelegate, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public content::NotificationObserver { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // void(GURL phishing_url, bool is_phishing). 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(GURL, bool)> ClientReportPhishingRequestCallback; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef base::Callback<void(GURL, bool)> ClientReportMalwareRequestCallback; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ClientSideDetectionService(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a client-side detection service. The service is initially 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disabled, use SetEnabledAndRefreshState() to start it. The caller takes 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ownership of the object. This function may return NULL. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ClientSideDetectionService* Create( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context_getter); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enables or disables the service, and refreshes the state of all renderers. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is usually called by the SafeBrowsingService, which tracks whether 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any profile uses these services at all. Disabling cancels any pending 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests; existing ClientSideDetectionHosts will have their callbacks 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called with "false" verdicts. Enabling starts downloading the model after 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a delay. In all cases, each render process is updated to match the state 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the SafeBrowsing preference for that profile. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetEnabledAndRefreshState(bool enabled); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled() const { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enabled_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // From the net::URLFetcherDelegate interface. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content::NotificationObserver overrides: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends a request to the SafeBrowsing servers with the ClientPhishingRequest. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The URL scheme of the |url()| in the request should be HTTP. This method 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // takes ownership of the |verdict| as well as the |callback| and calls the 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the callback once the result has come back from the server or if an error 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs during the fetch. If the service is disabled or an error occurs 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the phishing verdict will always be false. The callback is always called 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after SendClientReportPhishingRequest() returns and on the same thread as 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SendClientReportPhishingRequest() was called. You may set |callback| to 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NULL if you don't care about the server verdict. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SendClientReportPhishingRequest( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientPhishingRequest* verdict, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClientReportPhishingRequestCallback& callback); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Similar to above one, instead send ClientMalwareRequest 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SendClientReportMalwareRequest( 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClientMalwareRequest* verdict, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClientReportMalwareRequestCallback& callback); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the given IP address string falls within a private 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (unroutable) network block. Pages which are hosted on these IP addresses 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are exempt from client-side phishing detection. This is called by the 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ClientSideDetectionHost prior to sending the renderer a 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SafeBrowsingMsg_StartPhishingDetection IPC. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ip_address should be a dotted IPv4 address, or an unbracketed IPv6 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // address. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsPrivateIPAddress(const std::string& ip_address) const; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the given IP address is on the list of known bad IPs. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ip_address should be a dotted IPv4 address, or an unbracketed IPv6 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // address. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsBadIpAddress(const std::string& ip_address) const; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true and sets is_phishing if url is in the cache and valid. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetValidCachedResult(const GURL& url, bool* is_phishing); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the url is in the cache. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsInCache(const GURL& url); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Returns true if we have sent more than kMaxReportsPerInterval phishing 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // reports in the last kReportsInterval. 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool OverPhishingReportLimit(); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Returns true if we have sent more than kMaxReportsPerInterval malware 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // reports in the last kReportsInterval. 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool OverMalwareReportLimit(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use Create() method to create an instance of this object. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ClientSideDetectionService( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context_getter); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enum used to keep stats about why we fail to get the client model. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ClientModelStatus { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_SUCCESS, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_NOT_CHANGED, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_FETCH_FAILED, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_EMPTY, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_TOO_LARGE, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_PARSE_ERROR, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_MISSING_FIELDS, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_INVALID_VERSION_NUMBER, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_BAD_HASH_IDS, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_STATUS_MAX // Always add new values before this one. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts fetching the model from the network or the cache. This method 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is called periodically to check whether a new client model is available 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for download. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartFetchModel(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules the next fetch of the model. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ScheduleFetchModel(int64 delay_ms); // Virtual for testing. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method is called when we're done fetching the model either because 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we hit an error somewhere or because we're actually done fetch and 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // validating the model. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void EndFetchModel(ClientModelStatus status); // Virtual for testing. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ClientSideDetectionServiceTest; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, FetchModelTest); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, SetBadSubnets); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetEnabledAndRefreshState); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, IsBadIpAddress); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelHasValidHashIds); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CacheState holds all information necessary to respond to a caller without 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually making a HTTP request. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct CacheState { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_phishing; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time timestamp; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheState(bool phish, base::Time time); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<GURL, linked_ptr<CacheState> > PhishingCache; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A tuple of (IP address block, prefix size) representing a private 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IP address range. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::pair<net::IPAddressNumber, size_t> AddressRange; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maps a IPv6 subnet mask to a set of hashed IPv6 subnets. The IPv6 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subnets are in network order and hashed with sha256. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string /* subnet mask */, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string /* hashed subnet */> > BadSubnetMap; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char kClientReportMalwareUrl[]; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kClientReportPhishingUrl[]; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kClientModelUrl[]; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kMaxModelSizeBytes; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kMaxReportsPerInterval; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kClientModelFetchIntervalMs; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kInitialClientModelFetchDelayMs; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kReportsIntervalDays; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kNegativeCacheIntervalDays; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kPositiveCacheIntervalMinutes; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts sending the request to the client-side detection frontends. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method takes ownership of both pointers. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartClientReportPhishingRequest( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientPhishingRequest* verdict, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClientReportPhishingRequestCallback& callback); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StartClientReportMalwareRequest( 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClientMalwareRequest* verdict, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClientReportMalwareRequestCallback& callback); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by OnURLFetchComplete to handle the response from fetching the 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // model. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandleModelResponse(const net::URLFetcher* source, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequestStatus& status, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::ResponseCookies& cookies, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& data); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by OnURLFetchComplete to handle the server response from 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sending the client-side phishing request. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandlePhishingVerdict(const net::URLFetcher* source, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequestStatus& status, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::ResponseCookies& cookies, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& data); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called by OnURLFetchComplete to handle the server response from 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sending the client-side malware request. 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void HandleMalwareVerdict(const net::URLFetcher* source, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::URLRequestStatus& status, 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int response_code, 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::ResponseCookies& cookies, 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invalidate cache results which are no longer useful. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateCache(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Get the number of malware reports that we have sent over kReportsInterval. 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int GetMalwareNumReports(); 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Get the number of phishing reports that we have sent over kReportsInterval. 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int GetPhishingNumReports(); 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Get the number of reports that we have sent over kReportsInterval, and 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // trims off the old elements. 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int GetNumReports(std::queue<base::Time>* report_times); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the |private_networks_| vector with the network blocks 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that we consider non-public IP addresses. Returns true on success. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InitializePrivateNetworks(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the model to the given renderer. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendModelToProcess(content::RenderProcessHost* process); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as above but sends the model to all rendereres. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendModelToRenderers(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads the bad subnets from the client model and inserts them into 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |bad_subnets| for faster lookups. This method is static to simplify 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SetBadSubnets(const ClientSideModel& model, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BadSubnetMap* bad_subnets); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true iff all the hash id's in the client-side model point to 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // valid hashes in the model. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool ModelHasValidHashIds(const ClientSideModel& model); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the URL that will be used for phishing requests. 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static std::string GetClientReportUrl(const std::string& report_url); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the service is running or not. When the service is not running, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it won't download the model nor report detected phishing URLs. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled_; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string model_str_; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ClientSideModel> model_; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::TimeDelta> model_max_age_; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::URLFetcher> model_fetcher_; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of client report phishing request to the corresponding callback that 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has to be invoked when the request is done. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ClientReportInfo; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<const net::URLFetcher*, ClientReportInfo*> 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_phishing_reports_; 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<const net::URLFetcher*, ClientReportInfo*> 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_malware_reports_; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cache of completed requests. Used to satisfy requests for the same urls 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as long as the next request falls within our caching window (which is 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // determined by kNegativeCacheInterval and kPositiveCacheInterval). The 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size of this cache is limited by kMaxReportsPerDay * 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ceil(InDays(max(kNegativeCacheInterval, kPositiveCacheInterval))). 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(gcasto): Serialize this so that it doesn't reset on browser restart. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PhishingCache cache_; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Timestamp of when we sent a phishing request. Used to limit the number 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of phishing requests that we send in a day. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(gcasto): Serialize this so that it doesn't reset on browser restart. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::queue<base::Time> phishing_report_times_; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Timestamp of when we sent a malware request. Used to limit the number 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // of malware requests that we send in a day. 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::queue<base::Time> malware_report_times_; 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to asynchronously call the callbacks for 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SendClientReportPhishingRequest. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ClientSideDetectionService> weak_factory_; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The context we use to issue network requests. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The network blocks that we consider private IP address ranges. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AddressRange> private_networks_; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of bad subnets which are copied from the client model and put into 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this map to speed up lookups. 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BadSubnetMap bad_subnets_; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionService); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namepsace safe_browsing 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_ 344