| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "chrome/browser/safe_browsing/client_side_detection_host.h" | 5 #include "chrome/browser/safe_browsing/client_side_detection_host.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 NO_CLASSIFY_MAX // Always add new values before this one. | 151 NO_CLASSIFY_MAX // Always add new values before this one. |
| 152 }; | 152 }; |
| 153 | 153 |
| 154 // The destructor can be called either from the UI or the IO thread. | 154 // The destructor can be called either from the UI or the IO thread. |
| 155 virtual ~ShouldClassifyUrlRequest() { } | 155 virtual ~ShouldClassifyUrlRequest() { } |
| 156 | 156 |
| 157 void CheckCsdWhitelist(const GURL& url) { | 157 void CheckCsdWhitelist(const GURL& url) { |
| 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 159 if (!sb_service_ || sb_service_->MatchCsdWhitelistUrl(url)) { | 159 if (!sb_service_ || sb_service_->MatchCsdWhitelistUrl(url)) { |
| 160 // We're done. There is no point in going back to the UI thread. | 160 // We're done. There is no point in going back to the UI thread. |
| 161 VLOG(1) << "Skipping phishing classification for URL: " << url |
| 162 << " because it matches the csd whitelist"; |
| 161 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.PreClassificationCheckFail", | 163 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.PreClassificationCheckFail", |
| 162 NO_CLASSIFY_MATCH_CSD_WHITELIST, | 164 NO_CLASSIFY_MATCH_CSD_WHITELIST, |
| 163 NO_CLASSIFY_MAX); | 165 NO_CLASSIFY_MAX); |
| 164 return; | 166 return; |
| 165 } | 167 } |
| 166 | 168 |
| 167 BrowserThread::PostTask( | 169 BrowserThread::PostTask( |
| 168 BrowserThread::UI, | 170 BrowserThread::UI, |
| 169 FROM_HERE, | 171 FROM_HERE, |
| 170 NewRunnableMethod(this, | 172 NewRunnableMethod(this, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 200 << "not running classification for " << params_.url; | 202 << "not running classification for " << params_.url; |
| 201 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.PreClassificationCheckFail", | 203 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.PreClassificationCheckFail", |
| 202 NO_CLASSIFY_TOO_MANY_REPORTS, | 204 NO_CLASSIFY_TOO_MANY_REPORTS, |
| 203 NO_CLASSIFY_MAX); | 205 NO_CLASSIFY_MAX); |
| 204 return; | 206 return; |
| 205 } | 207 } |
| 206 | 208 |
| 207 // Everything checks out, so start classification. | 209 // Everything checks out, so start classification. |
| 208 // |tab_contents_| is safe to call as we will be destructed | 210 // |tab_contents_| is safe to call as we will be destructed |
| 209 // before it is. | 211 // before it is. |
| 212 VLOG(1) << "Instruct renderer to start phishing detection for URL: " |
| 213 << params_.url; |
| 210 RenderViewHost* rvh = tab_contents_->render_view_host(); | 214 RenderViewHost* rvh = tab_contents_->render_view_host(); |
| 211 rvh->Send(new SafeBrowsingMsg_StartPhishingDetection( | 215 rvh->Send(new SafeBrowsingMsg_StartPhishingDetection( |
| 212 rvh->routing_id(), params_.url)); | 216 rvh->routing_id(), params_.url)); |
| 213 } | 217 } |
| 214 | 218 |
| 215 // No need to protect |canceled_| with a lock because it is only read and | 219 // No need to protect |canceled_| with a lock because it is only read and |
| 216 // written by the UI thread. | 220 // written by the UI thread. |
| 217 bool canceled_; | 221 bool canceled_; |
| 218 ViewHostMsg_FrameNavigate_Params params_; | 222 ViewHostMsg_FrameNavigate_Params params_; |
| 219 TabContents* tab_contents_; | 223 TabContents* tab_contents_; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 DCHECK(csd_service_); | 338 DCHECK(csd_service_); |
| 335 // We parse the protocol buffer here. If we're unable to parse it we won't | 339 // We parse the protocol buffer here. If we're unable to parse it we won't |
| 336 // send the verdict further. | 340 // send the verdict further. |
| 337 scoped_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest); | 341 scoped_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest); |
| 338 if (csd_service_ && | 342 if (csd_service_ && |
| 339 verdict->ParseFromString(verdict_str) && | 343 verdict->ParseFromString(verdict_str) && |
| 340 verdict->IsInitialized()) { | 344 verdict->IsInitialized()) { |
| 341 // There shouldn't be any pending requests because we revoke them everytime | 345 // There shouldn't be any pending requests because we revoke them everytime |
| 342 // we navigate away. | 346 // we navigate away. |
| 343 DCHECK(!cb_factory_.HasPendingCallbacks()); | 347 DCHECK(!cb_factory_.HasPendingCallbacks()); |
| 348 VLOG(2) << "Start sending client phishing request for URL: " |
| 349 << verdict->url(); |
| 344 csd_service_->SendClientReportPhishingRequest( | 350 csd_service_->SendClientReportPhishingRequest( |
| 345 verdict.release(), // The service takes ownership of the verdict. | 351 verdict.release(), // The service takes ownership of the verdict. |
| 346 cb_factory_.NewCallback( | 352 cb_factory_.NewCallback( |
| 347 &ClientSideDetectionHost::MaybeShowPhishingWarning)); | 353 &ClientSideDetectionHost::MaybeShowPhishingWarning)); |
| 348 } | 354 } |
| 349 } | 355 } |
| 350 | 356 |
| 351 void ClientSideDetectionHost::MaybeShowPhishingWarning(GURL phishing_url, | 357 void ClientSideDetectionHost::MaybeShowPhishingWarning(GURL phishing_url, |
| 352 bool is_phishing) { | 358 bool is_phishing) { |
| 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 360 VLOG(2) << "Received server phishing verdict for URL:" << phishing_url |
| 361 << " is_phishing:" << is_phishing; |
| 354 if (is_phishing && | 362 if (is_phishing && |
| 355 CommandLine::ForCurrentProcess()->HasSwitch( | 363 CommandLine::ForCurrentProcess()->HasSwitch( |
| 356 switches::kEnableClientSidePhishingInterstitial)) { | 364 switches::kEnableClientSidePhishingInterstitial)) { |
| 357 DCHECK(tab_contents()); | 365 DCHECK(tab_contents()); |
| 358 // TODO(noelutz): this is not perfect. It's still possible that the | |
| 359 // user browses away before the interstitial is shown. Maybe we should | |
| 360 // stop all pending navigations? | |
| 361 if (sb_service_) { | 366 if (sb_service_) { |
| 362 // TODO(noelutz): refactor the SafeBrowsing service class and the | 367 SafeBrowsingService::UnsafeResource resource; |
| 363 // SafeBrowsing blocking page class so that we don't need to depend | 368 resource.url = phishing_url; |
| 364 // on the SafeBrowsingService here and so that we don't need to go | 369 resource.original_url = phishing_url; |
| 365 // through the IO message loop. | 370 resource.resource_type = ResourceType::MAIN_FRAME; |
| 366 std::vector<GURL> redirect_urls; | 371 resource.threat_type = SafeBrowsingService::CLIENT_SIDE_PHISHING_URL; |
| 367 BrowserThread::PostTask( | 372 resource.render_process_host_id = |
| 368 BrowserThread::IO, | 373 tab_contents()->GetRenderProcessHost()->id(); |
| 369 FROM_HERE, | 374 resource.render_view_id = |
| 370 NewRunnableMethod(sb_service_.get(), | 375 tab_contents()->render_view_host()->routing_id(); |
| 371 &SafeBrowsingService::DisplayBlockingPage, | 376 if (!sb_service_->IsWhitelisted(resource)) { |
| 372 phishing_url, phishing_url, | 377 // We need to stop any pending navigations, otherwise the interstital |
| 373 redirect_urls, | 378 // might not get created properly. |
| 374 // We only classify the main frame URL. | 379 tab_contents()->controller().DiscardNonCommittedEntries(); |
| 375 ResourceType::MAIN_FRAME, | 380 resource.client = new CsdClient(); // Will delete itself |
| 376 SafeBrowsingService::CLIENT_SIDE_PHISHING_URL, | 381 sb_service_->DoDisplayBlockingPage(resource); |
| 377 new CsdClient() /* will delete itself */, | 382 } |
| 378 tab_contents()->GetRenderProcessHost()->id(), | |
| 379 tab_contents()->render_view_host()->routing_id())); | |
| 380 } | 383 } |
| 381 } | 384 } |
| 382 } | 385 } |
| 383 | 386 |
| 384 void ClientSideDetectionHost::set_client_side_detection_service( | 387 void ClientSideDetectionHost::set_client_side_detection_service( |
| 385 ClientSideDetectionService* service) { | 388 ClientSideDetectionService* service) { |
| 386 csd_service_ = service; | 389 csd_service_ = service; |
| 387 } | 390 } |
| 388 | 391 |
| 389 void ClientSideDetectionHost::set_safe_browsing_service( | 392 void ClientSideDetectionHost::set_safe_browsing_service( |
| 390 SafeBrowsingService* service) { | 393 SafeBrowsingService* service) { |
| 391 sb_service_ = service; | 394 sb_service_ = service; |
| 392 } | 395 } |
| 393 | 396 |
| 394 } // namespace safe_browsing | 397 } // namespace safe_browsing |
| OLD | NEW |