client_side_detection_service.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/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 "googleurl/src/gurl.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.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) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if we have sent more than kMaxReportsPerInterval in the last 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // kReportsInterval. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OverReportLimit(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use Create() method to create an instance of this object. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ClientSideDetectionService( 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context_getter); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enum used to keep stats about why we fail to get the client model. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ClientModelStatus { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_SUCCESS, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_NOT_CHANGED, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_FETCH_FAILED, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_EMPTY, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_TOO_LARGE, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_PARSE_ERROR, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_MISSING_FIELDS, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_INVALID_VERSION_NUMBER, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_BAD_HASH_IDS, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MODEL_STATUS_MAX // Always add new values before this one. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts fetching the model from the network or the cache. This method 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is called periodically to check whether a new client model is available 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for download. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartFetchModel(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules the next fetch of the model. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ScheduleFetchModel(int64 delay_ms); // Virtual for testing. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method is called when we're done fetching the model either because 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we hit an error somewhere or because we're actually done fetch and 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // validating the model. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void EndFetchModel(ClientModelStatus status); // Virtual for testing. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ClientSideDetectionServiceTest; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, FetchModelTest); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, SetBadSubnets); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetEnabledAndRefreshState); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, IsBadIpAddress); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelHasValidHashIds); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CacheState holds all information necessary to respond to a caller without 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually making a HTTP request. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct CacheState { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_phishing; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time timestamp; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheState(bool phish, base::Time time); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<GURL, linked_ptr<CacheState> > PhishingCache; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A tuple of (IP address block, prefix size) representing a private 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IP address range. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::pair<net::IPAddressNumber, size_t> AddressRange; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maps a IPv6 subnet mask to a set of hashed IPv6 subnets. The IPv6 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subnets are in network order and hashed with sha256. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string /* subnet mask */, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string /* hashed subnet */> > BadSubnetMap; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char kClientReportMalwareUrl[]; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kClientReportPhishingUrl[]; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kClientModelUrl[]; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kMaxModelSizeBytes; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kMaxReportsPerInterval; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kClientModelFetchIntervalMs; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kInitialClientModelFetchDelayMs; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kReportsIntervalDays; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kNegativeCacheIntervalDays; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kPositiveCacheIntervalMinutes; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts sending the request to the client-side detection frontends. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method takes ownership of both pointers. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartClientReportPhishingRequest( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientPhishingRequest* verdict, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClientReportPhishingRequestCallback& callback); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StartClientReportMalwareRequest( 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClientMalwareRequest* verdict, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClientReportMalwareRequestCallback& callback); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by OnURLFetchComplete to handle the response from fetching the 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // model. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandleModelResponse(const net::URLFetcher* source, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequestStatus& status, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::ResponseCookies& cookies, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& data); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by OnURLFetchComplete to handle the server response from 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sending the client-side phishing request. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandlePhishingVerdict(const net::URLFetcher* source, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequestStatus& status, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::ResponseCookies& cookies, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& data); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called by OnURLFetchComplete to handle the server response from 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sending the client-side malware request. 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void HandleMalwareVerdict(const net::URLFetcher* source, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::URLRequestStatus& status, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int response_code, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::ResponseCookies& cookies, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invalidate cache results which are no longer useful. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateCache(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the number of phishing reports that we have sent over kReportsInterval 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetNumReports(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the |private_networks_| vector with the network blocks 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that we consider non-public IP addresses. Returns true on success. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InitializePrivateNetworks(); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the model to the given renderer. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendModelToProcess(content::RenderProcessHost* process); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as above but sends the model to all rendereres. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendModelToRenderers(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads the bad subnets from the client model and inserts them into 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |bad_subnets| for faster lookups. This method is static to simplify 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SetBadSubnets(const ClientSideModel& model, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BadSubnetMap* bad_subnets); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true iff all the hash id's in the client-side model point to 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // valid hashes in the model. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool ModelHasValidHashIds(const ClientSideModel& model); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the URL that will be used for phishing requests. 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static std::string GetClientReportUrl(const std::string& report_url); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the service is running or not. When the service is not running, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it won't download the model nor report detected phishing URLs. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled_; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string model_str_; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ClientSideModel> model_; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::TimeDelta> model_max_age_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::URLFetcher> model_fetcher_; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of client report phishing request to the corresponding callback that 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has to be invoked when the request is done. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ClientReportInfo; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<const net::URLFetcher*, ClientReportInfo*> 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_phishing_reports_; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<const net::URLFetcher*, ClientReportInfo*> 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_malware_reports_; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cache of completed requests. Used to satisfy requests for the same urls 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as long as the next request falls within our caching window (which is 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // determined by kNegativeCacheInterval and kPositiveCacheInterval). The 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size of this cache is limited by kMaxReportsPerDay * 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ceil(InDays(max(kNegativeCacheInterval, kPositiveCacheInterval))). 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(gcasto): Serialize this so that it doesn't reset on browser restart. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PhishingCache cache_; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Timestamp of when we sent a phishing request. Used to limit the number 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of phishing requests that we send in a day. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(gcasto): Serialize this so that it doesn't reset on browser restart. 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::queue<base::Time> phishing_report_times_; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to asynchronously call the callbacks for 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SendClientReportPhishingRequest. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ClientSideDetectionService> weak_factory_; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The context we use to issue network requests. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The network blocks that we consider private IP address ranges. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AddressRange> private_networks_; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of bad subnets which are copied from the client model and put into 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this map to speed up lookups. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BadSubnetMap bad_subnets_; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionService); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namepsace safe_browsing 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_ 329