| 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 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 proceeded_ = true; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 212 // Now that this interstitial is gone, we can show the new one. | 176 // Now that this interstitial is gone, we can show the new one. |
| 213 if (blocking_page) | 177 if (blocking_page) |
| 214 blocking_page->Show(); | 178 blocking_page->Show(); |
| 215 } | 179 } |
| 216 | 180 |
| 217 content::InterstitialPageDelegate::TypeID | 181 content::InterstitialPageDelegate::TypeID |
| 218 SafeBrowsingBlockingPage::GetTypeForTesting() const { | 182 SafeBrowsingBlockingPage::GetTypeForTesting() const { |
| 219 return SafeBrowsingBlockingPage::kTypeForTesting; | 183 return SafeBrowsingBlockingPage::kTypeForTesting; |
| 220 } | 184 } |
| 221 | 185 |
| 222 bool SafeBrowsingBlockingPage::ShouldCreateNewNavigation() const { | |
| 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, | 186 void SafeBrowsingBlockingPage::FinishThreatDetails(int64_t delay_ms, |
| 271 bool did_proceed, | 187 bool did_proceed, |
| 272 int num_visits) { | 188 int num_visits) { |
| 273 if (threat_details_.get() == NULL) | 189 if (threat_details_.get() == NULL) |
| 274 return; // Not all interstitials have threat details (eg., incognito mode). | 190 return; // Not all interstitials have threat details (eg., incognito mode). |
| 275 | 191 |
| 276 const bool enabled = | 192 const bool enabled = |
| 277 sb_error_ui_->is_extended_reporting_enabled() && | 193 sb_error_ui_->is_extended_reporting_enabled() && |
| 278 sb_error_ui_->is_extended_reporting_opt_in_allowed(); | 194 sb_error_ui_->is_extended_reporting_opt_in_allowed(); |
| 279 if (!enabled) | 195 if (!enabled) |
| 280 return; | 196 return; |
| 281 | 197 |
| 282 controller()->metrics_helper()->RecordUserInteraction( | 198 controller()->metrics_helper()->RecordUserInteraction( |
| 283 security_interstitials::MetricsHelper::EXTENDED_REPORTING_IS_ENABLED); | 199 security_interstitials::MetricsHelper::EXTENDED_REPORTING_IS_ENABLED); |
| 284 // Finish the malware details collection, send it over. | 200 // Finish the malware details collection, send it over. |
| 285 BrowserThread::PostDelayedTask( | 201 BrowserThread::PostDelayedTask( |
| 286 BrowserThread::IO, FROM_HERE, | 202 BrowserThread::IO, FROM_HERE, |
| 287 base::Bind(&ThreatDetails::FinishCollection, threat_details_, | 203 base::Bind(&ThreatDetails::FinishCollection, threat_details_, |
| 288 did_proceed, num_visits), | 204 did_proceed, num_visits), |
| 289 base::TimeDelta::FromMilliseconds(delay_ms)); | 205 base::TimeDelta::FromMilliseconds(delay_ms)); |
| 290 } | 206 } |
| 291 | 207 |
| 292 // static | 208 // static |
| 293 SafeBrowsingBlockingPage::UnsafeResourceMap* | |
| 294 SafeBrowsingBlockingPage::GetUnsafeResourcesMap() { | |
| 295 return g_unsafe_resource_map.Pointer(); | |
| 296 } | |
| 297 | |
| 298 // static | |
| 299 SafeBrowsingBlockingPage* SafeBrowsingBlockingPage::CreateBlockingPage( | 209 SafeBrowsingBlockingPage* SafeBrowsingBlockingPage::CreateBlockingPage( |
| 300 SafeBrowsingUIManager* ui_manager, | 210 BaseUIManager* ui_manager, |
| 301 WebContents* web_contents, | 211 WebContents* web_contents, |
| 302 const GURL& main_frame_url, | 212 const GURL& main_frame_url, |
| 303 const UnsafeResource& unsafe_resource) { | 213 const UnsafeResource& unsafe_resource) { |
| 304 std::vector<UnsafeResource> resources; | 214 std::vector<UnsafeResource> resources{unsafe_resource}; |
| 305 resources.push_back(unsafe_resource); | |
| 306 // Set up the factory if this has not been done already (tests do that | 215 // Set up the factory if this has not been done already (tests do that |
| 307 // before this method is called). | 216 // before this method is called). |
| 308 if (!factory_) | 217 if (!factory_) |
| 309 factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer(); | 218 factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer(); |
| 310 return factory_->CreateSafeBrowsingPage(ui_manager, web_contents, | 219 return factory_->CreateSafeBrowsingPage(ui_manager, web_contents, |
| 311 main_frame_url, resources); | 220 main_frame_url, resources); |
| 312 } | 221 } |
| 313 | 222 |
| 314 // static | 223 // static |
| 315 void SafeBrowsingBlockingPage::ShowBlockingPage( | 224 void SafeBrowsingBlockingPage::ShowBlockingPage( |
| 316 SafeBrowsingUIManager* ui_manager, | 225 BaseUIManager* ui_manager, |
| 317 const UnsafeResource& unsafe_resource) { | 226 const UnsafeResource& unsafe_resource) { |
| 318 DVLOG(1) << __func__ << " " << unsafe_resource.url.spec(); | 227 DVLOG(1) << __func__ << " " << unsafe_resource.url.spec(); |
| 319 WebContents* web_contents = unsafe_resource.web_contents_getter.Run(); | 228 WebContents* web_contents = unsafe_resource.web_contents_getter.Run(); |
| 320 | 229 |
| 321 if (!InterstitialPage::GetInterstitialPage(web_contents) || | 230 if (!InterstitialPage::GetInterstitialPage(web_contents) || |
| 322 !unsafe_resource.is_subresource) { | 231 !unsafe_resource.is_subresource) { |
| 323 // There is no interstitial currently showing in that tab, or we are about | 232 // 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 | 233 // 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. | 234 // interstitial, showing the new one will automatically hide the old one. |
| 326 content::NavigationEntry* entry = | 235 content::NavigationEntry* entry = |
| 327 unsafe_resource.GetNavigationEntryForResource(); | 236 unsafe_resource.GetNavigationEntryForResource(); |
| 328 SafeBrowsingBlockingPage* blocking_page = | 237 SafeBrowsingBlockingPage* blocking_page = |
| 329 CreateBlockingPage(ui_manager, web_contents, | 238 CreateBlockingPage(ui_manager, web_contents, |
| 330 entry ? entry->GetURL() : GURL(), unsafe_resource); | 239 entry ? entry->GetURL() : GURL(), unsafe_resource); |
| 331 blocking_page->Show(); | 240 blocking_page->Show(); |
| 332 return; | 241 return; |
| 333 } | 242 } |
| 334 | 243 |
| 335 // This is an interstitial for a page's resource, let's queue it. | 244 // This is an interstitial for a page's resource, let's queue it. |
| 336 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); | 245 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap(); |
| 337 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource); | 246 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource); |
| 338 } | 247 } |
| 339 | 248 |
| 340 // static | 249 // 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( | 250 std::string SafeBrowsingBlockingPage::GetSamplingEventName( |
| 402 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) { | 251 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) { |
| 403 switch (interstitial_reason) { | 252 switch (interstitial_reason) { |
| 404 case SafeBrowsingErrorUI::SB_REASON_MALWARE: | 253 case SafeBrowsingErrorUI::SB_REASON_MALWARE: |
| 405 return kEventNameMalware; | 254 return kEventNameMalware; |
| 406 case SafeBrowsingErrorUI::SB_REASON_HARMFUL: | 255 case SafeBrowsingErrorUI::SB_REASON_HARMFUL: |
| 407 return kEventNameHarmful; | 256 return kEventNameHarmful; |
| 408 case SafeBrowsingErrorUI::SB_REASON_PHISHING: | 257 case SafeBrowsingErrorUI::SB_REASON_PHISHING: |
| 409 return kEventNamePhishing; | 258 return kEventNamePhishing; |
| 410 default: | 259 default: |
| 411 return kEventNameOther; | 260 return kEventNameOther; |
| 412 } | 261 } |
| 413 } | 262 } |
| 414 | 263 |
| 415 // static | 264 // 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> | 265 std::unique_ptr<security_interstitials::SecurityInterstitialControllerClient> |
| 447 SafeBrowsingBlockingPage::CreateControllerClient( | 266 SafeBrowsingBlockingPage::CreateControllerClient( |
| 448 WebContents* web_contents, | 267 WebContents* web_contents, |
| 449 const UnsafeResourceList& unsafe_resources) { | 268 const UnsafeResourceList& unsafe_resources) { |
| 450 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason = | 269 SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason = |
| 451 GetInterstitialReason(unsafe_resources); | 270 GetInterstitialReason(unsafe_resources); |
| 452 GURL request_url(unsafe_resources[0].url); | 271 GURL request_url(unsafe_resources[0].url); |
| 453 security_interstitials::MetricsHelper::ReportDetails reporting_info; | 272 security_interstitials::MetricsHelper::ReportDetails reporting_info; |
| 454 reporting_info.metric_prefix = | 273 reporting_info.metric_prefix = |
| 455 GetMetricPrefix(unsafe_resources, interstitial_reason); | 274 GetMetricPrefix(unsafe_resources, interstitial_reason); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 466 | 285 |
| 467 return base::MakeUnique< | 286 return base::MakeUnique< |
| 468 security_interstitials::SecurityInterstitialControllerClient>( | 287 security_interstitials::SecurityInterstitialControllerClient>( |
| 469 web_contents, | 288 web_contents, |
| 470 std::move(metrics_helper), | 289 std::move(metrics_helper), |
| 471 profile->GetPrefs(), | 290 profile->GetPrefs(), |
| 472 g_browser_process->GetApplicationLocale(), | 291 g_browser_process->GetApplicationLocale(), |
| 473 GURL(chrome::kChromeUINewTabURL)); | 292 GURL(chrome::kChromeUINewTabURL)); |
| 474 } | 293 } |
| 475 | 294 |
| 476 void SafeBrowsingBlockingPage::PopulateInterstitialStrings( | |
| 477 base::DictionaryValue* load_time_data) { | |
| 478 sb_error_ui_->PopulateStringsForHTML(load_time_data); | |
| 479 } | |
| 480 | |
| 481 } // namespace safe_browsing | 295 } // namespace safe_browsing |
| OLD | NEW |