Chromium Code Reviews| 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 #include "chrome/browser/safe_browsing/ui_manager.h" | 5 #include "chrome/browser/safe_browsing/ui_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/debug/leak_tracker.h" | 10 #include "base/debug/leak_tracker.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 | 36 |
| 37 using content::BrowserThread; | 37 using content::BrowserThread; |
| 38 using content::NavigationEntry; | 38 using content::NavigationEntry; |
| 39 using content::WebContents; | 39 using content::WebContents; |
| 40 using safe_browsing::HitReport; | 40 using safe_browsing::HitReport; |
| 41 | 41 |
| 42 namespace { | 42 namespace { |
| 43 | 43 |
| 44 const void* const kWhitelistKey = &kWhitelistKey; | 44 const void* const kWhitelistKey = &kWhitelistKey; |
| 45 | 45 |
| 46 // A WhitelistUrlSet holds the set of URLs that have been whitelisted for a | |
| 47 // specific WebContents, along with pending entries that are still undecided. | |
| 46 class WhitelistUrlSet : public base::SupportsUserData::Data { | 48 class WhitelistUrlSet : public base::SupportsUserData::Data { |
| 47 public: | 49 public: |
| 48 WhitelistUrlSet() {} | 50 WhitelistUrlSet() {} |
| 49 | 51 |
| 50 bool Contains(const GURL url) { | 52 bool Contains(const GURL url) { |
| 51 auto iter = set_.find(url.GetWithEmptyPath()); | 53 auto iter = set_.find(url.GetWithEmptyPath()); |
| 52 return iter != set_.end(); | 54 return iter != set_.end(); |
| 53 } | 55 } |
| 54 | 56 |
| 55 void Insert(const GURL url) { set_.insert(url.GetWithEmptyPath()); } | 57 void Insert(const GURL url) { |
| 58 set_.insert(url.GetWithEmptyPath()); | |
| 59 pending_.erase(url.GetWithEmptyPath()); | |
| 60 } | |
| 61 | |
| 62 bool ContainsPending(const GURL url) { | |
| 63 auto iter = pending_.find(url.GetWithEmptyPath()); | |
|
estark
2016/08/25 06:54:06
optional nit: I'd have a slight preference for `re
felt
2016/08/25 15:17:27
Sure. Also updated Contains() for consistency.
| |
| 64 return iter != pending_.end(); | |
| 65 } | |
| 66 | |
| 67 void InsertPending(const GURL url) { | |
| 68 pending_.insert(url.GetWithEmptyPath()); | |
| 69 } | |
| 56 | 70 |
| 57 private: | 71 private: |
| 58 std::set<GURL> set_; | 72 std::set<GURL> set_; |
| 73 std::set<GURL> pending_; | |
| 59 | 74 |
| 60 DISALLOW_COPY_AND_ASSIGN(WhitelistUrlSet); | 75 DISALLOW_COPY_AND_ASSIGN(WhitelistUrlSet); |
| 61 }; | 76 }; |
| 62 | 77 |
| 63 } // namespace | 78 } // namespace |
| 64 | 79 |
| 65 namespace safe_browsing { | 80 namespace safe_browsing { |
| 66 | 81 |
| 67 // SafeBrowsingUIManager::UnsafeResource --------------------------------------- | 82 // SafeBrowsingUIManager::UnsafeResource --------------------------------------- |
| 68 | 83 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 bool proceed) { | 156 bool proceed) { |
| 142 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 157 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 143 for (const auto& resource : resources) { | 158 for (const auto& resource : resources) { |
| 144 if (!resource.callback.is_null()) { | 159 if (!resource.callback.is_null()) { |
| 145 DCHECK(resource.callback_thread); | 160 DCHECK(resource.callback_thread); |
| 146 resource.callback_thread->PostTask( | 161 resource.callback_thread->PostTask( |
| 147 FROM_HERE, base::Bind(resource.callback, proceed)); | 162 FROM_HERE, base::Bind(resource.callback, proceed)); |
| 148 } | 163 } |
| 149 | 164 |
| 150 if (proceed) | 165 if (proceed) |
| 151 AddToWhitelist(resource); | 166 AddToWhitelistUrlSet(resource, false /* Pending -> permanent */); |
|
estark
2016/08/25 06:54:06
I don't see pending URLs getting cleaned up anywhe
felt
2016/08/25 15:17:27
There isn't any need to explicitly remove them.
C
estark
2016/08/25 15:39:54
Ah, ok, I see. That sounds fine to me. Thanks for
| |
| 152 } | 167 } |
| 153 } | 168 } |
| 154 | 169 |
| 155 void SafeBrowsingUIManager::DisplayBlockingPage( | 170 void SafeBrowsingUIManager::DisplayBlockingPage( |
| 156 const UnsafeResource& resource) { | 171 const UnsafeResource& resource) { |
| 157 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 172 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 158 if (resource.is_subresource && !resource.is_subframe) { | 173 if (resource.is_subresource && !resource.is_subframe) { |
| 159 // Sites tagged as serving Unwanted Software should only show a warning for | 174 // Sites tagged as serving Unwanted Software should only show a warning for |
| 160 // main-frame or sub-frame resource. Similar warning restrictions should be | 175 // main-frame or sub-frame resource. Similar warning restrictions should be |
| 161 // applied to malware sites tagged as "landing sites" (see "Types of | 176 // applied to malware sites tagged as "landing sites" (see "Types of |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 prefs::kSafeBrowsingExtendedReportingEnabled); | 247 prefs::kSafeBrowsingExtendedReportingEnabled); |
| 233 hit_report.is_metrics_reporting_active = | 248 hit_report.is_metrics_reporting_active = |
| 234 ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); | 249 ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(); |
| 235 | 250 |
| 236 MaybeReportSafeBrowsingHit(hit_report); | 251 MaybeReportSafeBrowsingHit(hit_report); |
| 237 } | 252 } |
| 238 | 253 |
| 239 if (resource.threat_type != SB_THREAT_TYPE_SAFE) { | 254 if (resource.threat_type != SB_THREAT_TYPE_SAFE) { |
| 240 FOR_EACH_OBSERVER(Observer, observer_list_, OnSafeBrowsingHit(resource)); | 255 FOR_EACH_OBSERVER(Observer, observer_list_, OnSafeBrowsingHit(resource)); |
| 241 } | 256 } |
| 257 AddToWhitelistUrlSet(resource, true /* A decision is now pending */); | |
| 242 SafeBrowsingBlockingPage::ShowBlockingPage(this, resource); | 258 SafeBrowsingBlockingPage::ShowBlockingPage(this, resource); |
| 243 } | 259 } |
| 244 | 260 |
| 245 // A safebrowsing hit is sent after a blocking page for malware/phishing | 261 // A safebrowsing hit is sent after a blocking page for malware/phishing |
| 246 // or after the warning dialog for download urls, only for | 262 // or after the warning dialog for download urls, only for |
| 247 // UMA || extended_reporting users. | 263 // UMA || extended_reporting users. |
| 248 void SafeBrowsingUIManager::MaybeReportSafeBrowsingHit( | 264 void SafeBrowsingUIManager::MaybeReportSafeBrowsingHit( |
| 249 const HitReport& hit_report) { | 265 const HitReport& hit_report) { |
| 250 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 266 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 251 | 267 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 // etc). This happens on the IO thread. | 354 // etc). This happens on the IO thread. |
| 339 if (sb_service_.get() == NULL || sb_service_->ping_manager() == NULL) | 355 if (sb_service_.get() == NULL || sb_service_->ping_manager() == NULL) |
| 340 return; | 356 return; |
| 341 | 357 |
| 342 if (!serialized.empty()) { | 358 if (!serialized.empty()) { |
| 343 DVLOG(1) << "Sending serialized threat details."; | 359 DVLOG(1) << "Sending serialized threat details."; |
| 344 sb_service_->ping_manager()->ReportThreatDetails(serialized); | 360 sb_service_->ping_manager()->ReportThreatDetails(serialized); |
| 345 } | 361 } |
| 346 } | 362 } |
| 347 | 363 |
| 348 // Whitelist this domain in the current WebContents. Either add the | 364 // Record this domain in the current WebContents as either whitelisted or |
| 349 // domain to an existing WhitelistUrlSet, or create a new WhitelistUrlSet. | 365 // pending whitelisting (if an interstitial is currently displayed). If an |
| 350 void SafeBrowsingUIManager::AddToWhitelist(const UnsafeResource& resource) { | 366 // existing WhitelistUrlSet does not yet exist, create a new WhitelistUrlSet. |
| 367 void SafeBrowsingUIManager::AddToWhitelistUrlSet(const UnsafeResource& resource, | |
| 368 bool pending) { | |
| 351 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 369 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 352 | 370 |
| 353 WebContents* web_contents = resource.web_contents_getter.Run(); | 371 WebContents* web_contents = resource.web_contents_getter.Run(); |
| 354 WhitelistUrlSet* site_list = | 372 WhitelistUrlSet* site_list = |
| 355 static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); | 373 static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); |
| 356 if (!site_list) { | 374 if (!site_list) { |
| 357 site_list = new WhitelistUrlSet; | 375 site_list = new WhitelistUrlSet; |
| 358 web_contents->SetUserData(kWhitelistKey, site_list); | 376 web_contents->SetUserData(kWhitelistKey, site_list); |
| 359 } | 377 } |
| 360 | 378 |
| 361 GURL whitelisted_url; | 379 GURL whitelisted_url; |
| 362 if (resource.is_subresource) { | 380 if (resource.is_subresource) { |
| 363 NavigationEntry* entry = resource.GetNavigationEntryForResource(); | 381 NavigationEntry* entry = resource.GetNavigationEntryForResource(); |
| 364 if (!entry) | 382 if (!entry) |
| 365 return; | 383 return; |
| 366 whitelisted_url = entry->GetURL(); | 384 whitelisted_url = entry->GetURL(); |
| 367 } else { | 385 } else { |
| 368 whitelisted_url = resource.url; | 386 whitelisted_url = resource.url; |
| 369 } | 387 } |
| 370 | 388 |
| 371 site_list->Insert(whitelisted_url); | 389 if (pending) { |
| 390 site_list->InsertPending(whitelisted_url); | |
| 391 } else { | |
| 392 site_list->Insert(whitelisted_url); | |
| 393 } | |
| 372 } | 394 } |
| 373 | 395 |
| 374 bool SafeBrowsingUIManager::IsWhitelisted(const UnsafeResource& resource) { | 396 bool SafeBrowsingUIManager::IsWhitelisted(const UnsafeResource& resource) { |
| 375 NavigationEntry* entry = nullptr; | 397 NavigationEntry* entry = nullptr; |
| 376 if (resource.is_subresource) { | 398 if (resource.is_subresource) { |
| 377 entry = resource.GetNavigationEntryForResource(); | 399 entry = resource.GetNavigationEntryForResource(); |
| 378 } | 400 } |
| 379 return IsUrlWhitelistedForWebContents(resource.url, resource.is_subresource, | 401 return IsUrlWhitelistedOrPendingForWebContents( |
| 380 entry, | 402 resource.url, resource.is_subresource, entry, |
| 381 resource.web_contents_getter.Run()); | 403 resource.web_contents_getter.Run(), false); |
| 382 } | 404 } |
| 383 | 405 |
| 384 // Check if the user has already ignored a SB warning for this WebContents and | 406 // Check if the user has already seen and/or ignored a SB warning for this |
| 385 // top-level domain. | 407 // WebContents and top-level domain. |
| 386 bool SafeBrowsingUIManager::IsUrlWhitelistedForWebContents( | 408 bool SafeBrowsingUIManager::IsUrlWhitelistedOrPendingForWebContents( |
| 387 const GURL& url, | 409 const GURL& url, |
| 388 bool is_subresource, | 410 bool is_subresource, |
| 389 NavigationEntry* entry, | 411 NavigationEntry* entry, |
| 390 content::WebContents* web_contents) { | 412 content::WebContents* web_contents, |
| 413 bool whitelist_only) { | |
| 391 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 414 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 392 | 415 |
| 393 GURL maybe_whitelisted_url; | 416 GURL lookup_url; |
| 394 if (is_subresource) { | 417 if (is_subresource) { |
| 395 if (!entry) | 418 if (!entry) |
| 396 return false; | 419 return false; |
| 397 maybe_whitelisted_url = entry->GetURL(); | 420 lookup_url = entry->GetURL(); |
| 398 } else { | 421 } else { |
| 399 maybe_whitelisted_url = url; | 422 lookup_url = url; |
| 400 } | 423 } |
| 401 | 424 |
| 402 WhitelistUrlSet* site_list = | 425 WhitelistUrlSet* site_list = |
| 403 static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); | 426 static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); |
| 404 if (!site_list) | 427 if (!site_list) |
| 405 return false; | 428 return false; |
| 406 return site_list->Contains(maybe_whitelisted_url); | 429 |
| 430 bool whitelisted = site_list->Contains(lookup_url); | |
| 431 if (whitelist_only) { | |
| 432 return whitelisted; | |
| 433 } else { | |
| 434 return whitelisted || site_list->ContainsPending(lookup_url); | |
| 435 } | |
| 407 } | 436 } |
| 408 | 437 |
| 409 } // namespace safe_browsing | 438 } // namespace safe_browsing |
| OLD | NEW |