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/download_protection_service.h" | 5 #include "chrome/browser/safe_browsing/download_protection_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "chrome/browser/ui/browser.h" | 30 #include "chrome/browser/ui/browser.h" |
31 #include "chrome/browser/ui/browser_list.h" | 31 #include "chrome/browser/ui/browser_list.h" |
32 #include "chrome/common/safe_browsing/csd.pb.h" | 32 #include "chrome/common/safe_browsing/csd.pb.h" |
33 #include "chrome/common/safe_browsing/download_protection_util.h" | 33 #include "chrome/common/safe_browsing/download_protection_util.h" |
34 #include "chrome/common/safe_browsing/zip_analyzer.h" | 34 #include "chrome/common/safe_browsing/zip_analyzer.h" |
35 #include "chrome/common/url_constants.h" | 35 #include "chrome/common/url_constants.h" |
36 #include "components/google/core/browser/google_util.h" | 36 #include "components/google/core/browser/google_util.h" |
37 #include "content/public/browser/browser_thread.h" | 37 #include "content/public/browser/browser_thread.h" |
38 #include "content/public/browser/download_item.h" | 38 #include "content/public/browser/download_item.h" |
39 #include "content/public/browser/page_navigator.h" | 39 #include "content/public/browser/page_navigator.h" |
| 40 #include "crypto/sha2.h" |
40 #include "google_apis/google_api_keys.h" | 41 #include "google_apis/google_api_keys.h" |
41 #include "net/base/escape.h" | 42 #include "net/base/escape.h" |
42 #include "net/base/load_flags.h" | 43 #include "net/base/load_flags.h" |
43 #include "net/cert/x509_cert_types.h" | 44 #include "net/cert/x509_cert_types.h" |
44 #include "net/cert/x509_certificate.h" | 45 #include "net/cert/x509_certificate.h" |
45 #include "net/http/http_status_code.h" | 46 #include "net/http/http_status_code.h" |
46 #include "net/url_request/url_fetcher.h" | 47 #include "net/url_request/url_fetcher.h" |
47 #include "net/url_request/url_fetcher_delegate.h" | 48 #include "net/url_request/url_fetcher_delegate.h" |
48 #include "net/url_request/url_request_context_getter.h" | 49 #include "net/url_request/url_request_context_getter.h" |
49 #include "net/url_request/url_request_status.h" | 50 #include "net/url_request/url_request_status.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 DOWNLOAD_URL_CHECKS_CANCELED, | 132 DOWNLOAD_URL_CHECKS_CANCELED, |
132 DOWNLOAD_URL_CHECKS_MALWARE, | 133 DOWNLOAD_URL_CHECKS_MALWARE, |
133 | 134 |
134 DOWNLOAD_HASH_CHECKS_TOTAL, | 135 DOWNLOAD_HASH_CHECKS_TOTAL, |
135 DOWNLOAD_HASH_CHECKS_MALWARE, | 136 DOWNLOAD_HASH_CHECKS_MALWARE, |
136 | 137 |
137 // Memory space for histograms is determined by the max. | 138 // Memory space for histograms is determined by the max. |
138 // ALWAYS ADD NEW VALUES BEFORE THIS ONE. | 139 // ALWAYS ADD NEW VALUES BEFORE THIS ONE. |
139 DOWNLOAD_CHECKS_MAX | 140 DOWNLOAD_CHECKS_MAX |
140 }; | 141 }; |
| 142 |
| 143 // Prepares URLs to be put into a ping message. Currently this just shortens |
| 144 // data: URIs, other URLs are included verbatim. |
| 145 std::string SanitizeUrl(const GURL& url) { |
| 146 std::string spec = url.spec(); |
| 147 if (url.SchemeIs(url::kDataScheme)) { |
| 148 size_t comma_pos = spec.find(','); |
| 149 if (comma_pos != std::string::npos && comma_pos != spec.size() - 1) { |
| 150 std::string hash_value = crypto::SHA256HashString(spec); |
| 151 spec.erase(comma_pos + 1); |
| 152 spec += base::HexEncode(hash_value.data(), hash_value.size()); |
| 153 } |
| 154 } |
| 155 return spec; |
| 156 } |
| 157 |
141 } // namespace | 158 } // namespace |
142 | 159 |
143 // Parent SafeBrowsing::Client class used to lookup the bad binary | 160 // Parent SafeBrowsing::Client class used to lookup the bad binary |
144 // URL and digest list. There are two sub-classes (one for each list). | 161 // URL and digest list. There are two sub-classes (one for each list). |
145 class DownloadSBClient | 162 class DownloadSBClient |
146 : public SafeBrowsingDatabaseManager::Client, | 163 : public SafeBrowsingDatabaseManager::Client, |
147 public base::RefCountedThreadSafe<DownloadSBClient> { | 164 public base::RefCountedThreadSafe<DownloadSBClient> { |
148 public: | 165 public: |
149 DownloadSBClient( | 166 DownloadSBClient( |
150 const content::DownloadItem& item, | 167 const content::DownloadItem& item, |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 ClientDownloadRequest::DownloadType* type) { | 477 ClientDownloadRequest::DownloadType* type) { |
461 if (item.GetUrlChain().empty()) { | 478 if (item.GetUrlChain().empty()) { |
462 *reason = REASON_EMPTY_URL_CHAIN; | 479 *reason = REASON_EMPTY_URL_CHAIN; |
463 return false; | 480 return false; |
464 } | 481 } |
465 const GURL& final_url = item.GetUrlChain().back(); | 482 const GURL& final_url = item.GetUrlChain().back(); |
466 if (!final_url.is_valid() || final_url.is_empty()) { | 483 if (!final_url.is_valid() || final_url.is_empty()) { |
467 *reason = REASON_INVALID_URL; | 484 *reason = REASON_INVALID_URL; |
468 return false; | 485 return false; |
469 } | 486 } |
470 if ((!final_url.IsStandard() && !final_url.SchemeIsBlob()) || | 487 if ((!final_url.IsStandard() && !final_url.SchemeIsBlob() && |
| 488 !final_url.SchemeIs(url::kDataScheme)) || |
471 final_url.SchemeIsFile()) { | 489 final_url.SchemeIsFile()) { |
472 *reason = REASON_UNSUPPORTED_URL_SCHEME; | 490 *reason = REASON_UNSUPPORTED_URL_SCHEME; |
473 return false; | 491 return false; |
474 } | 492 } |
475 if (!download_protection_util::IsBinaryFile(target_path)) { | 493 if (!download_protection_util::IsBinaryFile(target_path)) { |
476 *reason = REASON_NOT_BINARY_FILE; | 494 *reason = REASON_NOT_BINARY_FILE; |
477 return false; | 495 return false; |
478 } | 496 } |
479 *type = download_protection_util::GetDownloadType(target_path); | 497 *type = download_protection_util::GetDownloadType(target_path); |
480 return true; | 498 return true; |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 | 708 |
691 void SendRequest() { | 709 void SendRequest() { |
692 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 710 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
693 | 711 |
694 // This is our last chance to check whether the request has been canceled | 712 // This is our last chance to check whether the request has been canceled |
695 // before sending it. | 713 // before sending it. |
696 if (!service_) | 714 if (!service_) |
697 return; | 715 return; |
698 | 716 |
699 ClientDownloadRequest request; | 717 ClientDownloadRequest request; |
700 request.set_url(item_->GetUrlChain().back().spec()); | 718 request.set_url(SanitizeUrl(item_->GetUrlChain().back())); |
701 request.mutable_digests()->set_sha256(item_->GetHash()); | 719 request.mutable_digests()->set_sha256(item_->GetHash()); |
702 request.set_length(item_->GetReceivedBytes()); | 720 request.set_length(item_->GetReceivedBytes()); |
703 for (size_t i = 0; i < item_->GetUrlChain().size(); ++i) { | 721 for (size_t i = 0; i < item_->GetUrlChain().size(); ++i) { |
704 ClientDownloadRequest::Resource* resource = request.add_resources(); | 722 ClientDownloadRequest::Resource* resource = request.add_resources(); |
705 resource->set_url(item_->GetUrlChain()[i].spec()); | 723 resource->set_url(SanitizeUrl(item_->GetUrlChain()[i])); |
706 if (i == item_->GetUrlChain().size() - 1) { | 724 if (i == item_->GetUrlChain().size() - 1) { |
707 // The last URL in the chain is the download URL. | 725 // The last URL in the chain is the download URL. |
708 resource->set_type(ClientDownloadRequest::DOWNLOAD_URL); | 726 resource->set_type(ClientDownloadRequest::DOWNLOAD_URL); |
709 resource->set_referrer(item_->GetReferrerUrl().spec()); | 727 resource->set_referrer(SanitizeUrl(item_->GetReferrerUrl())); |
710 DVLOG(2) << "dl url " << resource->url(); | 728 DVLOG(2) << "dl url " << resource->url(); |
711 if (!item_->GetRemoteAddress().empty()) { | 729 if (!item_->GetRemoteAddress().empty()) { |
712 resource->set_remote_ip(item_->GetRemoteAddress()); | 730 resource->set_remote_ip(item_->GetRemoteAddress()); |
713 DVLOG(2) << " dl url remote addr: " << resource->remote_ip(); | 731 DVLOG(2) << " dl url remote addr: " << resource->remote_ip(); |
714 } | 732 } |
715 DVLOG(2) << "dl referrer " << resource->referrer(); | 733 DVLOG(2) << "dl referrer " << resource->referrer(); |
716 } else { | 734 } else { |
717 DVLOG(2) << "dl redirect " << i << " " << resource->url(); | 735 DVLOG(2) << "dl redirect " << i << " " << resource->url(); |
718 resource->set_type(ClientDownloadRequest::DOWNLOAD_REDIRECT); | 736 resource->set_type(ClientDownloadRequest::DOWNLOAD_REDIRECT); |
719 } | 737 } |
720 // TODO(noelutz): fill out the remote IP addresses. | 738 // TODO(noelutz): fill out the remote IP addresses. |
721 } | 739 } |
722 // TODO(mattm): fill out the remote IP addresses for tab resources. | 740 // TODO(mattm): fill out the remote IP addresses for tab resources. |
723 for (size_t i = 0; i < tab_redirects_.size(); ++i) { | 741 for (size_t i = 0; i < tab_redirects_.size(); ++i) { |
724 ClientDownloadRequest::Resource* resource = request.add_resources(); | 742 ClientDownloadRequest::Resource* resource = request.add_resources(); |
725 DVLOG(2) << "tab redirect " << i << " " << tab_redirects_[i].spec(); | 743 DVLOG(2) << "tab redirect " << i << " " << tab_redirects_[i].spec(); |
726 resource->set_url(tab_redirects_[i].spec()); | 744 resource->set_url(SanitizeUrl(tab_redirects_[i])); |
727 resource->set_type(ClientDownloadRequest::TAB_REDIRECT); | 745 resource->set_type(ClientDownloadRequest::TAB_REDIRECT); |
728 } | 746 } |
729 if (tab_url_.is_valid()) { | 747 if (tab_url_.is_valid()) { |
730 ClientDownloadRequest::Resource* resource = request.add_resources(); | 748 ClientDownloadRequest::Resource* resource = request.add_resources(); |
731 resource->set_url(tab_url_.spec()); | 749 resource->set_url(SanitizeUrl(tab_url_)); |
732 DVLOG(2) << "tab url " << resource->url(); | 750 DVLOG(2) << "tab url " << resource->url(); |
733 resource->set_type(ClientDownloadRequest::TAB_URL); | 751 resource->set_type(ClientDownloadRequest::TAB_URL); |
734 if (tab_referrer_url_.is_valid()) { | 752 if (tab_referrer_url_.is_valid()) { |
735 resource->set_referrer(tab_referrer_url_.spec()); | 753 resource->set_referrer(SanitizeUrl(tab_referrer_url_)); |
736 DVLOG(2) << "tab referrer " << resource->referrer(); | 754 DVLOG(2) << "tab referrer " << resource->referrer(); |
737 } | 755 } |
738 } | 756 } |
739 | 757 |
740 request.set_user_initiated(item_->HasUserGesture()); | 758 request.set_user_initiated(item_->HasUserGesture()); |
741 request.set_file_basename( | 759 request.set_file_basename( |
742 item_->GetTargetFilePath().BaseName().AsUTF8Unsafe()); | 760 item_->GetTargetFilePath().BaseName().AsUTF8Unsafe()); |
743 request.set_download_type(type_); | 761 request.set_download_type(type_); |
744 request.mutable_signature()->CopyFrom(signature_info_); | 762 request.mutable_signature()->CopyFrom(signature_info_); |
745 request.mutable_image_headers()->CopyFrom(image_headers_); | 763 request.mutable_image_headers()->CopyFrom(image_headers_); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 GURL DownloadProtectionService::GetDownloadRequestUrl() { | 1128 GURL DownloadProtectionService::GetDownloadRequestUrl() { |
1111 GURL url(kDownloadRequestUrl); | 1129 GURL url(kDownloadRequestUrl); |
1112 std::string api_key = google_apis::GetAPIKey(); | 1130 std::string api_key = google_apis::GetAPIKey(); |
1113 if (!api_key.empty()) | 1131 if (!api_key.empty()) |
1114 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 1132 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
1115 | 1133 |
1116 return url; | 1134 return url; |
1117 } | 1135 } |
1118 | 1136 |
1119 } // namespace safe_browsing | 1137 } // namespace safe_browsing |
OLD | NEW |