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 |