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.
5 #ifndef CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_
6 #define CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_
11 #include "base/memory/ref_counted.h"
12 #include "base/time/time.h"
13 #include "base/timer/timer.h"
14 #include "chrome/browser/safe_browsing/database_manager.h"
15 #include "chrome/browser/safe_browsing/ui_manager.h"
16 #include "content/public/browser/resource_throttle.h"
17 #include "content/public/common/resource_type.h"
19 class ResourceDispatcherHost
;
25 // SafeBrowsingResourceThrottle checks that URLs are "safe" before
26 // navigating to them. To be considered "safe", a URL must not appear in the
27 // malware/phishing blacklists (see SafeBrowsingService for details).
29 // On desktop (ifdef SAFE_BROWSING_DB_LOCAL)
30 // -----------------------------------------
31 // This check is done before requesting the original URL, and additionally
32 // before following any subsequent redirect. In the common case the check
33 // completes synchronously (no match in the in-memory DB), so the request's
34 // flow is un-interrupted. However if the URL fails this quick check, it
35 // has the possibility of being on the blacklist. Now the request is
36 // deferred (prevented from starting), and a more expensive safe browsing
37 // check is begun (fetches the full hashes).
39 // On mobile (ifdef SAFE_BROWSING_DB_REMOTE):
40 // -----------------------------------------
41 // The check is started and runs in parallel with the resource load. If the
42 // check is not complete by the time the headers are loaded, the request is
43 // suspended until the URL is classified. We let the headers load on mobile
44 // since the RemoteSafeBrowsingDatabase checks always have some non-zero
45 // latency -- there no synchronous pass. This parallelism helps
46 // performance. Redirects are handled the same way as desktop so they
50 // Note that the safe browsing check takes at most kCheckUrlTimeoutMs
51 // milliseconds. If it takes longer than this, then the system defaults to
52 // treating the URL as safe.
54 // If the URL is classified as dangerous, a warning page is thrown up and
55 // the request remains suspended. If the user clicks "proceed" on warning
56 // page, we resume the request.
58 // Note: The ResourceThrottle interface is called in this order:
59 // WillStartRequest once, WillRedirectRequest zero or more times, and then
60 // WillProcessReponse once.
61 class SafeBrowsingResourceThrottle
62 : public content::ResourceThrottle
,
63 public SafeBrowsingDatabaseManager::Client
,
64 public base::SupportsWeakPtr
<SafeBrowsingResourceThrottle
> {
66 // Will construct a SafeBrowsingResourceThrottle, or return NULL
67 // if on Android and not in the field trial.
68 static SafeBrowsingResourceThrottle
* MaybeCreate(
69 net::URLRequest
* request
,
70 content::ResourceType resource_type
,
71 SafeBrowsingService
* sb_service
);
73 SafeBrowsingResourceThrottle(const net::URLRequest
* request
,
74 content::ResourceType resource_type
,
75 SafeBrowsingService
* sb_service
,
78 // content::ResourceThrottle implementation (called on IO thread):
79 void WillStartRequest(bool* defer
) override
;
80 void WillRedirectRequest(const net::RedirectInfo
& redirect_info
,
81 bool* defer
) override
;
82 void WillProcessResponse(bool* defer
) override
;
84 const char* GetNameForLogging() const override
;
86 // SafeBrowsingDabaseManager::Client implementation (called on IO thread):
87 void OnCheckBrowseUrlResult(const GURL
& url
,
89 const std::string
& metadata
) override
;
92 // Describes what phase of the check a throttle is in.
94 // Haven't started checking or checking is complete. Not deferred.
96 // We have one outstanding URL-check. Could be deferred.
98 // We're displaying a blocking page. Could be deferred.
99 STATE_DISPLAYING_BLOCKING_PAGE
,
102 // Describes what stage of the request got paused by the check.
107 DEFERRED_UNCHECKED_REDIRECT
, // unchecked_redirect_url_ is populated.
111 ~SafeBrowsingResourceThrottle() override
;
113 // SafeBrowsingService::UrlCheckCallback implementation.
114 void OnBlockingPageComplete(bool proceed
);
116 // Starts running |url| through the safe browsing check. Returns true if the
117 // URL is safe to visit. Otherwise returns false and will call
118 // OnBrowseUrlResult() when the check has completed.
119 bool CheckUrl(const GURL
& url
);
121 // Callback for when the safe browsing check (which was initiated by
122 // StartCheckingUrl()) has taken longer than kCheckUrlTimeoutMs.
123 void OnCheckUrlTimeout();
125 // Starts displaying the safe browsing interstitial page if it's not
126 // prerendering. Called on the UI thread.
127 static void StartDisplayingBlockingPage(
128 const base::WeakPtr
<SafeBrowsingResourceThrottle
>& throttle
,
129 scoped_refptr
<SafeBrowsingUIManager
> ui_manager
,
130 const SafeBrowsingUIManager::UnsafeResource
& resource
);
132 // Called on the IO thread if the request turned out to be for a prerendered
136 // Resumes the request, by continuing the deferred action (either starting the
137 // request, or following a redirect).
138 void ResumeRequest();
140 // True if we want to block the starting of requests until they're
141 // deemed safe. Otherwise we let the resource partially load.
142 const bool defer_at_start_
;
145 DeferState defer_state_
;
147 // The result of the most recent safe browsing check. Only valid to read this
148 // when state_ != STATE_CHECKING_URL.
149 SBThreatType threat_type_
;
151 // The time when we started deferring the request.
152 base::TimeTicks defer_start_time_
;
154 // Timer to abort the safe browsing check if it takes too long.
155 base::OneShotTimer
<SafeBrowsingResourceThrottle
> timer_
;
157 // The redirect chain for this resource
158 std::vector
<GURL
> redirect_urls_
;
160 // If in DEFERRED_UNCHECKED_REDIRECT state, this is the
161 // URL we still need to check before resuming.
162 GURL unchecked_redirect_url_
;
163 GURL url_being_checked_
;
165 scoped_refptr
<SafeBrowsingDatabaseManager
> database_manager_
;
166 scoped_refptr
<SafeBrowsingUIManager
> ui_manager_
;
167 const net::URLRequest
* request_
;
168 const bool is_subresource_
;
169 const bool is_subframe_
;
171 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingResourceThrottle
);
173 #endif // CHROME_BROWSER_RENDERER_HOST_SAFE_BROWSING_RESOURCE_THROTTLE_H_