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