OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 // Implementation of the SafeBrowsingBlockingPage class. | 5 // Implementation of the SafeBrowsingBlockingPage class. |
6 | 6 |
7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" | 7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" |
8 | 8 |
9 #include <string> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/command_line.h" | 9 #include "base/command_line.h" |
13 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
14 #include "base/macros.h" | |
15 #include "base/memory/ptr_util.h" | |
16 #include "base/strings/string_number_conversions.h" | |
17 #include "base/time/time.h" | |
18 #include "base/values.h" | |
19 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
20 #include "chrome/browser/interstitials/chrome_controller_client.h" | 12 #include "chrome/browser/interstitials/chrome_controller_client.h" |
| 13 #include "chrome/browser/interstitials/chrome_metrics_helper.h" |
21 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
22 #include "chrome/browser/renderer_preferences_util.h" | 15 #include "chrome/browser/renderer_preferences_util.h" |
23 #include "chrome/browser/safe_browsing/threat_details.h" | 16 #include "chrome/browser/safe_browsing/threat_details.h" |
24 #include "chrome/browser/safe_browsing/ui_manager.h" | |
25 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" |
26 #include "chrome/common/url_constants.h" | 18 #include "chrome/common/url_constants.h" |
27 #include "components/prefs/pref_service.h" | 19 #include "components/prefs/pref_service.h" |
28 #include "components/safe_browsing_db/safe_browsing_prefs.h" | 20 #include "components/safe_browsing_db/safe_browsing_prefs.h" |
29 #include "components/security_interstitials/content/security_interstitial_contro
ller_client.h" | |
30 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
31 #include "content/public/browser/interstitial_page.h" | 22 #include "content/public/browser/interstitial_page.h" |
32 #include "content/public/browser/navigation_entry.h" | 23 #include "content/public/browser/navigation_entry.h" |
33 #include "content/public/browser/user_metrics.h" | |
34 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
35 | 25 |
36 using base::UserMetricsAction; | |
37 using content::BrowserThread; | 26 using content::BrowserThread; |
38 using content::InterstitialPage; | 27 using content::InterstitialPage; |
39 using content::WebContents; | 28 using content::WebContents; |
40 using security_interstitials::SafeBrowsingErrorUI; | 29 using security_interstitials::SafeBrowsingErrorUI; |
41 using security_interstitials::SecurityInterstitialControllerClient; | 30 using security_interstitials::SecurityInterstitialControllerClient; |
42 | 31 |
43 namespace safe_browsing { | 32 namespace safe_browsing { |
44 | 33 |
45 namespace { | 34 namespace { |
46 | 35 |
47 // After a safe browsing interstitial where the user opted-in to the report | 36 // After a safe browsing interstitial where the user opted-in to the report |
48 // but clicked "proceed anyway", we delay the call to | 37 // but clicked "proceed anyway", we delay the call to |
49 // ThreatDetails::FinishCollection() by this much time (in | 38 // ThreatDetails::FinishCollection() by this much time (in |
50 // milliseconds). | 39 // milliseconds). |
51 const int64_t kThreatDetailsProceedDelayMilliSeconds = 3000; | 40 const int64_t kThreatDetailsProceedDelayMilliSeconds = 3000; |
52 | 41 |
53 // Constants for the Experience Sampling instrumentation. | 42 // Constants for the Experience Sampling instrumentation. |
54 const char kEventNameMalware[] = "safebrowsing_interstitial_"; | 43 const char kEventNameMalware[] = "safebrowsing_interstitial_"; |
55 const char kEventNameHarmful[] = "harmful_interstitial_"; | 44 const char kEventNameHarmful[] = "harmful_interstitial_"; |
56 const char kEventNamePhishing[] = "phishing_interstitial_"; | 45 const char kEventNamePhishing[] = "phishing_interstitial_"; |
57 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; | 46 const char kEventNameOther[] = "safebrowsing_other_interstitial_"; |
58 | 47 |
59 base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap> | |
60 g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER; | |
61 | |
62 } // namespace | 48 } // namespace |
63 | 49 |
64 // static | 50 // static |
65 SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL; | 51 SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL; |
66 | 52 |
67 // The default SafeBrowsingBlockingPageFactory. Global, made a singleton so we | 53 // The default SafeBrowsingBlockingPageFactory. Global, made a singleton so we |
68 // don't leak it. | 54 // don't leak it. |
69 class SafeBrowsingBlockingPageFactoryImpl | 55 class SafeBrowsingBlockingPageFactoryImpl |
70 : public SafeBrowsingBlockingPageFactory { | 56 : public SafeBrowsingBlockingPageFactory { |
71 public: | 57 public: |
72 SafeBrowsingBlockingPage* CreateSafeBrowsingPage( | 58 SafeBrowsingBlockingPage* CreateSafeBrowsingPage( |
73 SafeBrowsingUIManager* ui_manager, | 59 BaseUIManager* ui_manager, |
74 WebContents* web_contents, | 60 WebContents* web_contents, |
75 const GURL& main_frame_url, | 61 const GURL& main_frame_url, |
76 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) | 62 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) |
77 override { | 63 override { |
| 64 // Create appropriate display options for this blocking page. |
| 65 PrefService* prefs = |
| 66 Profile::FromBrowserContext(web_contents->GetBrowserContext()) |
| 67 ->GetPrefs(); |
| 68 bool is_extended_reporting_opt_in_allowed = |
| 69 prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingOptInAllowed); |
| 70 bool is_proceed_anyway_disabled = |
| 71 prefs->GetBoolean(prefs::kSafeBrowsingProceedAnywayDisabled); |
| 72 SafeBrowsingErrorUI::SBErrorDisplayOptions display_options( |
| 73 BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources), |
| 74 is_extended_reporting_opt_in_allowed, |
| 75 web_contents->GetBrowserContext()->IsOffTheRecord(), |
| 76 IsExtendedReportingEnabled(*prefs), IsScout(*prefs), |
| 77 is_proceed_anyway_disabled); |
| 78 |
78 return new SafeBrowsingBlockingPage(ui_manager, web_contents, | 79 return new SafeBrowsingBlockingPage(ui_manager, web_contents, |
79 main_frame_url, unsafe_resources); | 80 main_frame_url, unsafe_resources, |
| 81 display_options); |
80 } | 82 } |
81 | 83 |
82 private: | 84 private: |
83 friend struct base::DefaultLazyInstanceTraits< | 85 friend struct base::DefaultLazyInstanceTraits< |
84 SafeBrowsingBlockingPageFactoryImpl>; | 86 SafeBrowsingBlockingPageFactoryImpl>; |
85 | 87 |
86 SafeBrowsingBlockingPageFactoryImpl() { } | 88 SafeBrowsingBlockingPageFactoryImpl() { } |
87 | 89 |
88 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageFactoryImpl); | 90 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageFactoryImpl); |
89 }; | 91 }; |
90 | 92 |
91 static base::LazyInstance<SafeBrowsingBlockingPageFactoryImpl> | 93 static base::LazyInstance<SafeBrowsingBlockingPageFactoryImpl> |
92 g_safe_browsing_blocking_page_factory_impl = LAZY_INSTANCE_INITIALIZER; | 94 g_safe_browsing_blocking_page_factory_impl = LAZY_INSTANCE_INITIALIZER; |
93 | 95 |
94 // static | 96 // static |
95 content::InterstitialPageDelegate::TypeID | 97 content::InterstitialPageDelegate::TypeID |
96 SafeBrowsingBlockingPage::kTypeForTesting = | 98 SafeBrowsingBlockingPage::kTypeForTesting = |
97 &SafeBrowsingBlockingPage::kTypeForTesting; | 99 &SafeBrowsingBlockingPage::kTypeForTesting; |
98 | 100 |
99 SafeBrowsingBlockingPage::SafeBrowsingBlockingPage( | 101 SafeBrowsingBlockingPage::SafeBrowsingBlockingPage( |
100 SafeBrowsingUIManager* ui_manager, | 102 BaseUIManager* ui_manager, |
101 WebContents* web_contents, | 103 WebContents* web_contents, |
102 const GURL& main_frame_url, | 104 const GURL& main_frame_url, |
103 const UnsafeResourceList& unsafe_resources) | 105 const UnsafeResourceList& unsafe_resources, |
104 : SecurityInterstitialPage( | 106 const SafeBrowsingErrorUI::SBErrorDisplayOptions& display_options) |
| 107 : BaseBlockingPage( |
| 108 ui_manager, |
105 web_contents, | 109 web_contents, |
106 unsafe_resources[0].url, | 110 unsafe_resources[0].url, |
107 CreateControllerClient(web_contents, unsafe_resources)), | 111 unsafe_resources, |
108 threat_details_proceed_delay_ms_(kThreatDetailsProceedDelayMilliSeconds), | 112 CreateControllerClient(web_contents, unsafe_resources), |
109 ui_manager_(ui_manager), | 113 display_options), |
110 main_frame_url_(main_frame_url), | 114 threat_details_proceed_delay_ms_(kThreatDetailsProceedDelayMilliSeconds) { |
111 unsafe_resources_(unsafe_resources), | |
112 proceeded_(false) { | |
113 // Computes display options based on user profile and blocked resource. | |
114 bool is_main_frame_load_blocked = IsMainPageLoadBlocked(unsafe_resources); | |
115 SafeBrowsingErrorUI::SBErrorDisplayOptions display_options( | |
116 is_main_frame_load_blocked, | |
117 IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingOptInAllowed), | |
118 web_contents->GetBrowserContext()->IsOffTheRecord(), | |
119 IsExtendedReportingEnabled(*controller()->GetPrefService()), | |
120 IsScout(*controller()->GetPrefService()), | |
121 IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)); | |
122 sb_error_ui_ = base::MakeUnique<SafeBrowsingErrorUI>( | |
123 unsafe_resources[0].url, main_frame_url_, | |
124 GetInterstitialReason(unsafe_resources), display_options, | |
125 g_browser_process->GetApplicationLocale(), | |
126 base::Time::NowFromSystemTime(), controller()); | |
127 | |
128 if (!is_main_frame_load_blocked) { | |
129 navigation_entry_index_to_remove_ = | |
130 web_contents->GetController().GetLastCommittedEntryIndex(); | |
131 } else { | |
132 navigation_entry_index_to_remove_ = -1; | |
133 } | |
134 | |
135 // Start computing threat details. They will be sent only | 115 // Start computing threat details. They will be sent only |
136 // if the user opts-in on the blocking page later. | 116 // if the user opts-in on the blocking page later. |
137 // If there's more than one malicious resources, it means the user | 117 // If there's more than one malicious resources, it means the user |
138 // clicked through the first warning, so we don't prepare additional | 118 // clicked through the first warning, so we don't prepare additional |
139 // reports. | 119 // reports. |
140 if (unsafe_resources.size() == 1 && | 120 if (unsafe_resources.size() == 1 && |
141 ShouldReportThreatDetails(unsafe_resources[0].threat_type) && | 121 ShouldReportThreatDetails(unsafe_resources[0].threat_type) && |
142 threat_details_.get() == NULL && | 122 threat_details_.get() == NULL && |
143 sb_error_ui_->CanShowExtendedReportingOption()) { | 123 sb_error_ui()->CanShowExtendedReportingOption()) { |
144 threat_details_ = ThreatDetails::NewThreatDetails(ui_manager_, web_contents, | 124 threat_details_ = ThreatDetails::NewThreatDetails(ui_manager, web_contents, |
145 unsafe_resources[0]); | 125 unsafe_resources[0]); |
146 } | 126 } |
147 } | 127 } |
148 | 128 |
149 bool SafeBrowsingBlockingPage::ShouldReportThreatDetails( | 129 bool SafeBrowsingBlockingPage::ShouldReportThreatDetails( |
150 SBThreatType threat_type) { | 130 SBThreatType threat_type) { |
151 return threat_type == SB_THREAT_TYPE_URL_PHISHING || | 131 return threat_type == SB_THREAT_TYPE_URL_PHISHING || |
152 threat_type == SB_THREAT_TYPE_URL_MALWARE || | 132 threat_type == SB_THREAT_TYPE_URL_MALWARE || |
153 threat_type == SB_THREAT_TYPE_URL_UNWANTED || | 133 threat_type == SB_THREAT_TYPE_URL_UNWANTED || |
154 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL || | 134 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL || |
155 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL; | 135 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL; |
156 } | 136 } |
157 | 137 |
158 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { | 138 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() { |
159 } | 139 } |
160 | 140 |
161 void SafeBrowsingBlockingPage::CommandReceived(const std::string& page_cmd) { | |
162 if (page_cmd == "\"pageLoadComplete\"") { | |
163 // content::WaitForRenderFrameReady sends this message when the page | |
164 // load completes. Ignore it. | |
165 return; | |
166 } | |
167 | |
168 int command = 0; | |
169 bool retval = base::StringToInt(page_cmd, &command); | |
170 DCHECK(retval) << page_cmd; | |
171 | |
172 sb_error_ui_->HandleCommand( | |
173 static_cast<security_interstitials::SecurityInterstitialCommands>( | |
174 command)); | |
175 } | |
176 | |
177 void SafeBrowsingBlockingPage::OverrideRendererPrefs( | 141 void SafeBrowsingBlockingPage::OverrideRendererPrefs( |
178 content::RendererPreferences* prefs) { | 142 content::RendererPreferences* prefs) { |
179 Profile* profile = Profile::FromBrowserContext( | 143 Profile* profile = Profile::FromBrowserContext( |
180 web_contents()->GetBrowserContext()); | 144 web_contents()->GetBrowserContext()); |
181 renderer_preferences_util::UpdateFromSystemSettings( | 145 renderer_preferences_util::UpdateFromSystemSettings( |
182 prefs, profile, web_contents()); | 146 prefs, profile, web_contents()); |
183 } | 147 } |
184 | 148 |
185 void SafeBrowsingBlockingPage::OnProceed() { | 149 void SafeBrowsingBlockingPage::OnProceed() { |
186 proceeded_ = true; | 150 set_proceeded(true); |
187 // Send the threat details, if we opted to. | 151 // Send the threat details, if we opted to. |
188 FinishThreatDetails(threat_details_proceed_delay_ms_, true, /* did_proceed */ | 152 FinishThreatDetails( |
189 controller()->metrics_helper()->NumVisits()); | 153 base::TimeDelta::FromMilliseconds(threat_details_proceed_delay_ms_), |
| 154 true, /* did_proceed */ |
| 155 controller()->metrics_helper()->NumVisits()); |
190 | 156 |
191 ui_manager_->OnBlockingPageDone(unsafe_resources_, true, web_contents(), | 157 ui_manager()->OnBlockingPageDone(unsafe_resources(), true, web_contents(), |
192 main_frame_url_); | 158 main_frame_url()); |
193 | 159 |
194 // Check to see if some new notifications of unsafe resources have been | 160 // Check to see if some new notifications of unsafe resources have been |
195 // received while we were showing the interstitial. | 161 // received while we were showing the interstitial. |
196 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); | 162 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); |
197 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents()); | 163 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents()); |
198 SafeBrowsingBlockingPage* blocking_page = NULL; | 164 SafeBrowsingBlockingPage* blocking_page = NULL; |
199 if (iter != unsafe_resource_map->end() && !iter->second.empty()) { | 165 if (iter != unsafe_resource_map->end() && !iter->second.empty()) { |
200 // All queued unsafe resources should be for the same page: | 166 // All queued unsafe resources should be for the same page: |
201 content::NavigationEntry* entry = | 167 content::NavigationEntry* entry = |
202 iter->second[0].GetNavigationEntryForResource(); | 168 iter->second[0].GetNavigationEntryForResource(); |
203 // Build an interstitial for all the unsafe resources notifications. | 169 // Build an interstitial for all the unsafe resources notifications. |
204 // Don't show it now as showing an interstitial while an interstitial is | 170 // Don't show it now as showing an interstitial while an interstitial is |
205 // already showing would cause DontProceed() to be invoked. | 171 // already showing would cause DontProceed() to be invoked. |
206 blocking_page = factory_->CreateSafeBrowsingPage( | 172 blocking_page = factory_->CreateSafeBrowsingPage( |
207 ui_manager_, web_contents(), entry ? entry->GetURL() : GURL(), | 173 ui_manager(), web_contents(), entry ? entry->GetURL() : GURL(), |
208 iter->second); | 174 iter->second); |
209 unsafe_resource_map->erase(iter); | 175 unsafe_resource_map->erase(iter); |
210 } | 176 } |
211 | 177 |
212 // Now that this interstitial is gone, we can show the new one. | 178 // Now that this interstitial is gone, we can show the new one. |
213 if (blocking_page) | 179 if (blocking_page) |
214 blocking_page->Show(); | 180 blocking_page->Show(); |
215 } | 181 } |
216 | 182 |
217 content::InterstitialPageDelegate::TypeID | 183 content::InterstitialPageDelegate::TypeID |
218 SafeBrowsingBlockingPage::GetTypeForTesting() const { | 184 SafeBrowsingBlockingPage::GetTypeForTesting() const { |
219 return SafeBrowsingBlockingPage::kTypeForTesting; | 185 return SafeBrowsingBlockingPage::kTypeForTesting; |
220 } | 186 } |
221 | 187 |
222 bool SafeBrowsingBlockingPage::ShouldCreateNewNavigation() const { | 188 void SafeBrowsingBlockingPage::FinishThreatDetails(const base::TimeDelta& delay, |
223 return sb_error_ui_->is_main_frame_load_blocked(); | |
224 } | |
225 | |
226 void SafeBrowsingBlockingPage::OnDontProceed() { | |
227 // We could have already called Proceed(), in which case we must not notify | |
228 // the SafeBrowsingUIManager again, as the client has been deleted. | |
229 if (proceeded_) | |
230 return; | |
231 | |
232 if (!sb_error_ui_->is_proceed_anyway_disabled()) { | |
233 controller()->metrics_helper()->RecordUserDecision( | |
234 security_interstitials::MetricsHelper::DONT_PROCEED); | |
235 } | |
236 | |
237 // Send the malware details, if we opted to. | |
238 FinishThreatDetails(0, false /* did_proceed */, | |
239 controller()->metrics_helper()->NumVisits()); // No delay | |
240 | |
241 ui_manager_->OnBlockingPageDone(unsafe_resources_, false, web_contents(), | |
242 main_frame_url_); | |
243 | |
244 // The user does not want to proceed, clear the queued unsafe resources | |
245 // notifications we received while the interstitial was showing. | |
246 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); | |
247 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents()); | |
248 if (iter != unsafe_resource_map->end() && !iter->second.empty()) { | |
249 ui_manager_->OnBlockingPageDone(iter->second, false, web_contents(), | |
250 main_frame_url_); | |
251 unsafe_resource_map->erase(iter); | |
252 } | |
253 | |
254 // We don't remove the navigation entry if the tab is being destroyed as this | |
255 // would trigger a navigation that would cause trouble as the render view host | |
256 // for the tab has by then already been destroyed. We also don't delete the | |
257 // current entry if it has been committed again, which is possible on a page | |
258 // that had a subresource warning. | |
259 int last_committed_index = | |
260 web_contents()->GetController().GetLastCommittedEntryIndex(); | |
261 if (navigation_entry_index_to_remove_ != -1 && | |
262 navigation_entry_index_to_remove_ != last_committed_index && | |
263 !web_contents()->IsBeingDestroyed()) { | |
264 CHECK(web_contents()->GetController().RemoveEntryAtIndex( | |
265 navigation_entry_index_to_remove_)); | |
266 navigation_entry_index_to_remove_ = -1; | |
267 } | |
268 } | |
269 | |
270 void SafeBrowsingBlockingPage::FinishThreatDetails(int64_t delay_ms, | |
271 bool did_proceed, | 189 bool did_proceed, |
272 int num_visits) { | 190 int num_visits) { |
273 if (threat_details_.get() == NULL) | 191 if (threat_details_.get() == NULL) |
274 return; // Not all interstitials have threat details (eg., incognito mode). | 192 return; // Not all interstitials have threat details (eg., incognito mode). |
275 | 193 |
276 const bool enabled = | 194 const bool enabled = |
277 sb_error_ui_->is_extended_reporting_enabled() && | 195 sb_error_ui()->is_extended_reporting_enabled() && |
278 sb_error_ui_->is_extended_reporting_opt_in_allowed(); | 196 sb_error_ui()->is_extended_reporting_opt_in_allowed(); |
279 if (!enabled) | 197 if (!enabled) |
280 return; | 198 return; |
281 | 199 |
282 controller()->metrics_helper()->RecordUserInteraction( | 200 controller()->metrics_helper()->RecordUserInteraction( |
283 security_interstitials::MetricsHelper::EXTENDED_REPORTING_IS_ENABLED); | 201 security_interstitials::MetricsHelper::EXTENDED_REPORTING_IS_ENABLED); |
284 // Finish the malware details collection, send it over. | 202 // Finish the malware details collection, send it over. |
285 BrowserThread::PostDelayedTask( | 203 BrowserThread::PostDelayedTask( |
286 BrowserThread::IO, FROM_HERE, | 204 BrowserThread::IO, FROM_HERE, |
287 base::Bind(&ThreatDetails::FinishCollection, threat_details_, | 205 base::Bind(&ThreatDetails::FinishCollection, threat_details_, |
288 did_proceed, num_visits), | 206 did_proceed, num_visits), |
289 base::TimeDelta::FromMilliseconds(delay_ms)); | 207 delay); |
290 } | |
291 | |
292 // static | |
293 SafeBrowsingBlockingPage::UnsafeResourceMap* | |
294 SafeBrowsingBlockingPage::GetUnsafeResourcesMap() { | |
295 return g_unsafe_resource_map.Pointer(); | |
296 } | 208 } |
297 | 209 |
298 // static | 210 // static |
299 SafeBrowsingBlockingPage* SafeBrowsingBlockingPage::CreateBlockingPage( | 211 SafeBrowsingBlockingPage* SafeBrowsingBlockingPage::CreateBlockingPage( |
300 SafeBrowsingUIManager* ui_manager, | 212 BaseUIManager* ui_manager, |
301 WebContents* web_contents, | 213 WebContents* web_contents, |
302 const GURL& main_frame_url, | 214 const GURL& main_frame_url, |
303 const UnsafeResource& unsafe_resource) { | 215 const UnsafeResource& unsafe_resource) { |
304 std::vector<UnsafeResource> resources; | 216 const UnsafeResourceList resources{unsafe_resource}; |
305 resources.push_back(unsafe_resource); | |
306 // Set up the factory if this has not been done already (tests do that | 217 // Set up the factory if this has not been done already (tests do that |
307 // before this method is called). | 218 // before this method is called). |
308 if (!factory_) | 219 if (!factory_) |
309 factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer(); | 220 factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer(); |
310 return factory_->CreateSafeBrowsingPage(ui_manager, web_contents, | 221 return factory_->CreateSafeBrowsingPage(ui_manager, web_contents, |
311 main_frame_url, resources); | 222 main_frame_url, resources); |
312 } | 223 } |
313 | 224 |
314 // static | 225 // static |
315 void SafeBrowsingBlockingPage::ShowBlockingPage( | 226 void SafeBrowsingBlockingPage::ShowBlockingPage( |
316 SafeBrowsingUIManager* ui_manager, | 227 BaseUIManager* ui_manager, |
317 const UnsafeResource& unsafe_resource) { | 228 const UnsafeResource& unsafe_resource) { |
318 DVLOG(1) << __func__ << " " << unsafe_resource.url.spec(); | 229 DVLOG(1) << __func__ << " " << unsafe_resource.url.spec(); |
319 WebContents* web_contents = unsafe_resource.web_contents_getter.Run(); | 230 WebContents* web_contents = unsafe_resource.web_contents_getter.Run(); |
320 | 231 |
321 if (!InterstitialPage::GetInterstitialPage(web_contents) || | 232 if (!InterstitialPage::GetInterstitialPage(web_contents) || |
322 !unsafe_resource.is_subresource) { | 233 !unsafe_resource.is_subresource) { |
323 // There is no interstitial currently showing in that tab, or we are about | 234 // There is no interstitial currently showing in that tab, or we are about |
324 // to display a new one for the main frame. If there is already an | 235 // to display a new one for the main frame. If there is already an |
325 // interstitial, showing the new one will automatically hide the old one. | 236 // interstitial, showing the new one will automatically hide the old one. |
326 content::NavigationEntry* entry = | 237 content::NavigationEntry* entry = |
327 unsafe_resource.GetNavigationEntryForResource(); | 238 unsafe_resource.GetNavigationEntryForResource(); |
328 SafeBrowsingBlockingPage* blocking_page = | 239 SafeBrowsingBlockingPage* blocking_page = |
329 CreateBlockingPage(ui_manager, web_contents, | 240 CreateBlockingPage(ui_manager, web_contents, |
330 entry ? entry->GetURL() : GURL(), unsafe_resource); | 241 entry ? entry->GetURL() : GURL(), unsafe_resource); |
331 blocking_page->Show(); | 242 blocking_page->Show(); |
332 return; | 243 return; |
333 } | 244 } |
334 | 245 |
335 // This is an interstitial for a page's resource, let's queue it. | 246 // This is an interstitial for a page's resource, let's queue it. |
336 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); | 247 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); |
337 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource); | 248 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource); |
338 } | 249 } |
339 | 250 |
340 // static | 251 // static |
341 bool SafeBrowsingBlockingPage::IsMainPageLoadBlocked( | |
342 const UnsafeResourceList& unsafe_resources) { | |
343 // If there is more than one unsafe resource, the main page load must not be | |
344 // blocked. Otherwise, check if the one resource is. | |
345 return unsafe_resources.size() == 1 && | |
346 unsafe_resources[0].IsMainPageLoadBlocked(); | |
347 } | |
348 | |
349 // static | |
350 std::string SafeBrowsingBlockingPage::GetMetricPrefix( | |
351 const UnsafeResourceList& unsafe_resources, | |
352 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) { | |
353 bool primary_subresource = unsafe_resources[0].is_subresource; | |
354 switch (interstitial_reason) { | |
355 case SafeBrowsingErrorUI::SB_REASON_MALWARE: | |
356 return primary_subresource ? "malware_subresource" : "malware"; | |
357 case SafeBrowsingErrorUI::SB_REASON_HARMFUL: | |
358 return primary_subresource ? "harmful_subresource" : "harmful"; | |
359 case SafeBrowsingErrorUI::SB_REASON_PHISHING: | |
360 ThreatPatternType threat_pattern_type = | |
361 unsafe_resources[0].threat_metadata.threat_pattern_type; | |
362 if (threat_pattern_type == ThreatPatternType::PHISHING || | |
363 threat_pattern_type == ThreatPatternType::NONE) | |
364 return primary_subresource ? "phishing_subresource" : "phishing"; | |
365 else if (threat_pattern_type == ThreatPatternType::SOCIAL_ENGINEERING_ADS) | |
366 return primary_subresource ? "social_engineering_ads_subresource" | |
367 : "social_engineering_ads"; | |
368 else if (threat_pattern_type == | |
369 ThreatPatternType::SOCIAL_ENGINEERING_LANDING) | |
370 return primary_subresource ? "social_engineering_landing_subresource" | |
371 : "social_engineering_landing"; | |
372 } | |
373 NOTREACHED(); | |
374 return "unkown_metric_prefix"; | |
375 } | |
376 | |
377 // We populate a parallel set of metrics to differentiate some threat sources. | |
378 // static | |
379 std::string SafeBrowsingBlockingPage::GetExtraMetricsSuffix( | |
380 const UnsafeResourceList& unsafe_resources) { | |
381 switch (unsafe_resources[0].threat_source) { | |
382 case safe_browsing::ThreatSource::DATA_SAVER: | |
383 return "from_data_saver"; | |
384 case safe_browsing::ThreatSource::REMOTE: | |
385 case safe_browsing::ThreatSource::LOCAL_PVER3: | |
386 // REMOTE and LOCAL_PVER3 can be distinguished in the logs | |
387 // by platform type: Remote is mobile, local_pver3 is desktop. | |
388 return "from_device"; | |
389 case safe_browsing::ThreatSource::LOCAL_PVER4: | |
390 return "from_device_v4"; | |
391 case safe_browsing::ThreatSource::CLIENT_SIDE_DETECTION: | |
392 return "from_client_side_detection"; | |
393 case safe_browsing::ThreatSource::UNKNOWN: | |
394 break; | |
395 } | |
396 NOTREACHED(); | |
397 return std::string(); | |
398 } | |
399 | |
400 // static | |
401 std::string SafeBrowsingBlockingPage::GetSamplingEventName( | 252 std::string SafeBrowsingBlockingPage::GetSamplingEventName( |
402 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) { | 253 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) { |
403 switch (interstitial_reason) { | 254 switch (interstitial_reason) { |
404 case SafeBrowsingErrorUI::SB_REASON_MALWARE: | 255 case SafeBrowsingErrorUI::SB_REASON_MALWARE: |
405 return kEventNameMalware; | 256 return kEventNameMalware; |
406 case SafeBrowsingErrorUI::SB_REASON_HARMFUL: | 257 case SafeBrowsingErrorUI::SB_REASON_HARMFUL: |
407 return kEventNameHarmful; | 258 return kEventNameHarmful; |
408 case SafeBrowsingErrorUI::SB_REASON_PHISHING: | 259 case SafeBrowsingErrorUI::SB_REASON_PHISHING: |
409 return kEventNamePhishing; | 260 return kEventNamePhishing; |
410 default: | 261 default: |
411 return kEventNameOther; | 262 return kEventNameOther; |
412 } | 263 } |
413 } | 264 } |
414 | 265 |
415 // static | 266 // static |
416 SafeBrowsingErrorUI::SBInterstitialReason | |
417 SafeBrowsingBlockingPage::GetInterstitialReason( | |
418 const UnsafeResourceList& unsafe_resources) { | |
419 bool malware = false; | |
420 bool harmful = false; | |
421 bool phishing = false; | |
422 for (UnsafeResourceList::const_iterator iter = unsafe_resources.begin(); | |
423 iter != unsafe_resources.end(); ++iter) { | |
424 const SafeBrowsingUIManager::UnsafeResource& resource = *iter; | |
425 safe_browsing::SBThreatType threat_type = resource.threat_type; | |
426 if (threat_type == SB_THREAT_TYPE_URL_MALWARE || | |
427 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) { | |
428 malware = true; | |
429 } else if (threat_type == SB_THREAT_TYPE_URL_UNWANTED) { | |
430 harmful = true; | |
431 } else { | |
432 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING || | |
433 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL); | |
434 phishing = true; | |
435 } | |
436 } | |
437 DCHECK(phishing || malware || harmful); | |
438 if (malware) | |
439 return SafeBrowsingErrorUI::SB_REASON_MALWARE; | |
440 else if (harmful) | |
441 return SafeBrowsingErrorUI::SB_REASON_HARMFUL; | |
442 return SafeBrowsingErrorUI::SB_REASON_PHISHING; | |
443 } | |
444 | |
445 // static | |
446 std::unique_ptr<security_interstitials::SecurityInterstitialControllerClient> | 267 std::unique_ptr<security_interstitials::SecurityInterstitialControllerClient> |
447 SafeBrowsingBlockingPage::CreateControllerClient( | 268 SafeBrowsingBlockingPage::CreateControllerClient( |
448 WebContents* web_contents, | 269 WebContents* web_contents, |
449 const UnsafeResourceList& unsafe_resources) { | 270 const UnsafeResourceList& unsafe_resources) { |
450 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason = | 271 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason = |
451 GetInterstitialReason(unsafe_resources); | 272 GetInterstitialReason(unsafe_resources); |
452 GURL request_url(unsafe_resources[0].url); | 273 GURL request_url(unsafe_resources[0].url); |
453 security_interstitials::MetricsHelper::ReportDetails reporting_info; | 274 security_interstitials::MetricsHelper::ReportDetails reporting_info; |
454 reporting_info.metric_prefix = | 275 reporting_info.metric_prefix = |
455 GetMetricPrefix(unsafe_resources, interstitial_reason); | 276 GetMetricPrefix(unsafe_resources, interstitial_reason); |
(...skipping 10 matching lines...) Expand all Loading... |
466 | 287 |
467 return base::MakeUnique< | 288 return base::MakeUnique< |
468 security_interstitials::SecurityInterstitialControllerClient>( | 289 security_interstitials::SecurityInterstitialControllerClient>( |
469 web_contents, | 290 web_contents, |
470 std::move(metrics_helper), | 291 std::move(metrics_helper), |
471 profile->GetPrefs(), | 292 profile->GetPrefs(), |
472 g_browser_process->GetApplicationLocale(), | 293 g_browser_process->GetApplicationLocale(), |
473 GURL(chrome::kChromeUINewTabURL)); | 294 GURL(chrome::kChromeUINewTabURL)); |
474 } | 295 } |
475 | 296 |
476 void SafeBrowsingBlockingPage::PopulateInterstitialStrings( | |
477 base::DictionaryValue* load_time_data) { | |
478 sb_error_ui_->PopulateStringsForHTML(load_time_data); | |
479 } | |
480 | |
481 } // namespace safe_browsing | 297 } // namespace safe_browsing |
OLD | NEW |