Home | History | Annotate | Download | only in safe_browsing
      1 // Copyright (c) 2012 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 // Classes for managing the SafeBrowsing interstitial pages.
      6 //
      7 // When a user is about to visit a page the SafeBrowsing system has deemed to
      8 // be malicious, either as malware or a phishing page, we show an interstitial
      9 // page with some options (go back, continue) to give the user a chance to avoid
     10 // the harmful page.
     11 //
     12 // The SafeBrowsingBlockingPage is created by the SafeBrowsingUIManager on the
     13 // UI thread when we've determined that a page is malicious. The operation of
     14 // the blocking page occurs on the UI thread, where it waits for the user to
     15 // make a decision about what to do: either go back or continue on.
     16 //
     17 // The blocking page forwards the result of the user's choice back to the
     18 // SafeBrowsingUIManager so that we can cancel the request for the new page,
     19 // or allow it to continue.
     20 //
     21 // A web page may contain several resources flagged as malware/phishing.  This
     22 // results into more than one interstitial being shown.  On the first unsafe
     23 // resource received we show an interstitial.  Any subsequent unsafe resource
     24 // notifications while the first interstitial is showing is queued.  If the user
     25 // decides to proceed in the first interstitial, we display all queued unsafe
     26 // resources in a new interstitial.
     27 
     28 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_
     29 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_
     30 
     31 #include <map>
     32 #include <string>
     33 #include <vector>
     34 
     35 #include "base/gtest_prod_util.h"
     36 #include "base/task/cancelable_task_tracker.h"
     37 #include "base/time/time.h"
     38 #include "chrome/browser/history/history_service.h"
     39 #include "chrome/browser/safe_browsing/ui_manager.h"
     40 #include "content/public/browser/interstitial_page_delegate.h"
     41 #include "url/gurl.h"
     42 
     43 class MalwareDetails;
     44 class SafeBrowsingBlockingPageFactory;
     45 
     46 namespace base {
     47 class DictionaryValue;
     48 class MessageLoop;
     49 }
     50 
     51 namespace content {
     52 class InterstitialPage;
     53 class WebContents;
     54 }
     55 
     56 #if defined(ENABLE_EXTENSIONS)
     57 namespace extensions {
     58 class ExperienceSamplingEvent;
     59 }
     60 #endif
     61 
     62 class SafeBrowsingBlockingPage : public content::InterstitialPageDelegate {
     63  public:
     64   typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource;
     65   typedef std::vector<UnsafeResource> UnsafeResourceList;
     66   typedef std::map<content::WebContents*, UnsafeResourceList> UnsafeResourceMap;
     67 
     68   virtual ~SafeBrowsingBlockingPage();
     69 
     70   // Creates a blocking page. Use ShowBlockingPage if you don't need to access
     71   // the blocking page directly.
     72   static SafeBrowsingBlockingPage* CreateBlockingPage(
     73       SafeBrowsingUIManager* ui_manager,
     74       content::WebContents* web_contents,
     75       const UnsafeResource& unsafe_resource);
     76 
     77   // Shows a blocking page warning the user about phishing/malware for a
     78   // specific resource.
     79   // You can call this method several times, if an interstitial is already
     80   // showing, the new one will be queued and displayed if the user decides
     81   // to proceed on the currently showing interstitial.
     82   static void ShowBlockingPage(
     83       SafeBrowsingUIManager* ui_manager, const UnsafeResource& resource);
     84 
     85   // Makes the passed |factory| the factory used to instantiate
     86   // SafeBrowsingBlockingPage objects. Useful for tests.
     87   static void RegisterFactory(SafeBrowsingBlockingPageFactory* factory) {
     88     factory_ = factory;
     89   }
     90 
     91   // InterstitialPageDelegate method:
     92   virtual std::string GetHTMLContents() OVERRIDE;
     93   virtual void OnProceed() OVERRIDE;
     94   virtual void OnDontProceed() OVERRIDE;
     95   virtual void CommandReceived(const std::string& command) OVERRIDE;
     96   virtual void OverrideRendererPrefs(
     97       content::RendererPreferences* prefs) OVERRIDE;
     98 
     99  protected:
    100   friend class SafeBrowsingBlockingPageTest;
    101   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest,
    102                            ProceedThenDontProceed);
    103 
    104   void DontCreateViewForTesting();
    105   void Show();
    106   void SetReportingPreference(bool report);
    107   void UpdateReportingPref();  // Used for the transition from old to new pref.
    108 
    109   // Don't instantiate this class directly, use ShowBlockingPage instead.
    110   SafeBrowsingBlockingPage(SafeBrowsingUIManager* ui_manager,
    111                            content::WebContents* web_contents,
    112                            const UnsafeResourceList& unsafe_resources);
    113 
    114   // After a malware interstitial where the user opted-in to the
    115   // report but clicked "proceed anyway", we delay the call to
    116   // MalwareDetails::FinishCollection() by this much time (in
    117   // milliseconds), in order to get data from the blocked resource itself.
    118   int64 malware_details_proceed_delay_ms_;
    119   content::InterstitialPage* interstitial_page() const {
    120     return interstitial_page_;
    121   }
    122 
    123   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest,
    124       MalwareReportsTransitionDisabled);
    125   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest,
    126       MalwareReportsToggling);
    127 
    128   // These enums are used for histograms.  Don't reorder, delete, or insert
    129   // elements.  New elements should be added before MAX_ACTION only.
    130   enum Decision {
    131     SHOW,
    132     PROCEED,
    133     DONT_PROCEED,
    134     PROCEEDING_DISABLED,
    135     MAX_DECISION
    136   };
    137   enum Interaction {
    138     TOTAL_VISITS,
    139     SHOW_ADVANCED,
    140     SHOW_PRIVACY_POLICY,
    141     SHOW_DIAGNOSTIC,
    142     SHOW_LEARN_MORE,
    143     MAX_INTERACTION
    144   };
    145 
    146   // Record a user decision or interaction to the appropriate UMA histogram.
    147   void RecordUserDecision(Decision decision);
    148   void RecordUserInteraction(Interaction interaction);
    149 
    150   // Used to query the HistoryService to see if the URL is in history. For UMA.
    151   void OnGotHistoryCount(bool success, int num_visits, base::Time first_visit);
    152 
    153   // Checks if we should even show the malware details option. For example, we
    154   // don't show it in incognito mode.
    155   bool CanShowMalwareDetailsOption();
    156 
    157   // Called when the insterstitial is going away. If there is a
    158   // pending malware details object, we look at the user's
    159   // preferences, and if the option to send malware details is
    160   // enabled, the report is scheduled to be sent on the |ui_manager_|.
    161   void FinishMalwareDetails(int64 delay_ms);
    162 
    163   // Returns the boolean value of the given |pref| from the PrefService of the
    164   // Profile associated with |web_contents_|.
    165   bool IsPrefEnabled(const char* pref);
    166 
    167   // A list of SafeBrowsingUIManager::UnsafeResource for a tab that the user
    168   // should be warned about.  They are queued when displaying more than one
    169   // interstitial at a time.
    170   static UnsafeResourceMap* GetUnsafeResourcesMap();
    171 
    172   // Notifies the SafeBrowsingUIManager on the IO thread whether to proceed
    173   // or not for the |resources|.
    174   static void NotifySafeBrowsingUIManager(
    175       SafeBrowsingUIManager* ui_manager,
    176       const UnsafeResourceList& resources, bool proceed);
    177 
    178   // Returns true if the passed |unsafe_resources| is blocking the load of
    179   // the main page.
    180   static bool IsMainPageLoadBlocked(
    181       const UnsafeResourceList& unsafe_resources);
    182 
    183   friend class SafeBrowsingBlockingPageFactoryImpl;
    184 
    185   // For reporting back user actions.
    186   SafeBrowsingUIManager* ui_manager_;
    187   base::MessageLoop* report_loop_;
    188 
    189   // True if the interstitial is blocking the main page because it is on one
    190   // of our lists.  False if a subresource is being blocked, or in the case of
    191   // client-side detection where the interstitial is shown after page load
    192   // finishes.
    193   bool is_main_frame_load_blocked_;
    194 
    195   // The index of a navigation entry that should be removed when DontProceed()
    196   // is invoked, -1 if not entry should be removed.
    197   int navigation_entry_index_to_remove_;
    198 
    199   // The list of unsafe resources this page is warning about.
    200   UnsafeResourceList unsafe_resources_;
    201 
    202   // A MalwareDetails object that we start generating when the
    203   // blocking page is shown. The object will be sent when the warning
    204   // is gone (if the user enables the feature).
    205   scoped_refptr<MalwareDetails> malware_details_;
    206 
    207   bool proceeded_;
    208 
    209   content::WebContents* web_contents_;
    210   GURL url_;
    211   content::InterstitialPage* interstitial_page_;  // Owns us
    212 
    213   // Whether the interstitial should create a view.
    214   bool create_view_;
    215 
    216   // Which type of interstitial this is.
    217   enum {
    218     TYPE_MALWARE,
    219     TYPE_HARMFUL,
    220     TYPE_PHISHING,
    221   } interstitial_type_;
    222 
    223   // The factory used to instantiate SafeBrowsingBlockingPage objects.
    224   // Usefull for tests, so they can provide their own implementation of
    225   // SafeBrowsingBlockingPage.
    226   static SafeBrowsingBlockingPageFactory* factory_;
    227 
    228   // How many times is this same URL in history? Used for histogramming.
    229   int num_visits_;
    230   base::CancelableTaskTracker request_tracker_;
    231 
    232  private:
    233   // Fills the passed dictionary with the values to be passed to the template
    234   // when creating the HTML.
    235   void PopulateMalwareLoadTimeData(base::DictionaryValue* load_time_data);
    236   void PopulateHarmfulLoadTimeData(base::DictionaryValue* load_time_data);
    237   void PopulatePhishingLoadTimeData(base::DictionaryValue* load_time_data);
    238 
    239 #if defined(ENABLE_EXTENSIONS)
    240   scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_;
    241 #endif
    242 
    243   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPage);
    244 };
    245 
    246 // Factory for creating SafeBrowsingBlockingPage.  Useful for tests.
    247 class SafeBrowsingBlockingPageFactory {
    248  public:
    249   virtual ~SafeBrowsingBlockingPageFactory() { }
    250 
    251   virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
    252       SafeBrowsingUIManager* ui_manager,
    253       content::WebContents* web_contents,
    254       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) = 0;
    255 };
    256 
    257 #endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_
    258