15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/ping_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/env_vars.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/google_api_keys.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SafeBrowsingPingManager implementation ---------------------------------- 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingPingManager* SafeBrowsingPingManager::Create( 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context_getter, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SafeBrowsingProtocolConfig& config) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SafeBrowsingPingManager(request_context_getter, config); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingPingManager::SafeBrowsingPingManager( 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context_getter, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SafeBrowsingProtocolConfig& config) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : client_name_(config.client_name), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_context_getter_(request_context_getter), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_prefix_(config.url_prefix) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!url_prefix_.empty()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_ = SafeBrowsingProtocolManagerHelper::Version(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingPingManager::~SafeBrowsingPingManager() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete in-progress safebrowsing reports (hits and details). 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers(safebrowsing_reports_.begin(), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) safebrowsing_reports_.end()); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// net::URLFetcherDelegate implementation ---------------------------------- 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All SafeBrowsing request responses are handled here. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingPingManager::OnURLFetchComplete( 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLFetcher* source) { 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Reports::iterator sit = safebrowsing_reports_.find(source); 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(sit != safebrowsing_reports_.end()); 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delete *sit; 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) safebrowsing_reports_.erase(sit); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sends a SafeBrowsing "hit" for UMA users. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingPingManager::ReportSafeBrowsingHit( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& malicious_url, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& page_url, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_subresource, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBThreatType threat_type, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& post_data) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL report_url = SafeBrowsingHitUrl(malicious_url, page_url, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) referrer_url, is_subresource, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_type); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLFetcher* report = net::URLFetcher::Create( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_url, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) post_data.empty() ? net::URLFetcher::GET : net::URLFetcher::POST, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report->SetLoadFlags(net::LOAD_DISABLE_CACHE); 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) report->SetRequestContext(request_context_getter_.get()); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!post_data.empty()) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report->SetUploadData("text/plain", post_data); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) safebrowsing_reports_.insert(report); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report->Start(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sends malware details for users who opt-in. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingPingManager::ReportMalwareDetails( 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& report) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL report_url = MalwareDetailsUrl(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLFetcher* fetcher = net::URLFetcher::Create( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_url, net::URLFetcher::POST, this); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fetcher->SetRequestContext(request_context_getter_.get()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->SetUploadData("application/octet-stream", report); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't try too hard to send reports on failures. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->SetAutomaticallyRetryOn5xx(false); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->Start(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) safebrowsing_reports_.insert(fetcher); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL SafeBrowsingPingManager::SafeBrowsingHitUrl( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& malicious_url, const GURL& page_url, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, bool is_subresource, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBThreatType threat_type) const { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(threat_type == SB_THREAT_TYPE_URL_MALWARE || 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_type == SB_THREAT_TYPE_URL_PHISHING || 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_type == SB_THREAT_TYPE_BINARY_MALWARE_URL || 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_type == SB_THREAT_TYPE_BINARY_MALWARE_HASH || 106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL || 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = SafeBrowsingProtocolManagerHelper::ComposeUrl( 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url_prefix_, "report", client_name_, version_, std::string()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string threat_list = "none"; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (threat_type) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SB_THREAT_TYPE_URL_MALWARE: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_list = "malblhit"; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SB_THREAT_TYPE_URL_PHISHING: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_list = "phishblhit"; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SB_THREAT_TYPE_BINARY_MALWARE_URL: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_list = "binurlhit"; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SB_THREAT_TYPE_BINARY_MALWARE_HASH: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_list = "binhashhit"; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threat_list = "phishcsdhit"; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL: 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) threat_list = "malcsdhit"; 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GURL(base::StringPrintf("%s&evts=%s&evtd=%s&evtr=%s&evhr=%s&evtb=%d", 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.c_str(), threat_list.c_str(), 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeQueryParamValue(malicious_url.spec(), true).c_str(), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeQueryParamValue(page_url.spec(), true).c_str(), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeQueryParamValue(referrer_url.spec(), true).c_str(), 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_subresource)); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL SafeBrowsingPingManager::MalwareDetailsUrl() const { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = base::StringPrintf( 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s/clientreport/malware?client=%s&appver=%s&pver=1.0", 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_prefix_.c_str(), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_name_.c_str(), 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_.c_str()); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string api_key = google_apis::GetAPIKey(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!api_key.empty()) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&url, "&key=%s", 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeQueryParamValue(api_key, true).c_str()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GURL(url); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 154