This source file includes following definitions.
- RecordDetailedUserAction
- CreateSafeBrowsingPage
- num_visits_
- CanShowMalwareDetailsOption
- CommandReceived
- OverrideRendererPrefs
- SetReportingPreference
- OnProceed
- OnDontProceed
- OnGotHistoryCount
- RecordUserAction
- RecordUserReactionTime
- FinishMalwareDetails
- IsPrefEnabled
- NotifySafeBrowsingUIManager
- GetUnsafeResourcesMap
- ShowBlockingPage
- IsMainPageLoadBlocked
- GetHTMLContents
- PopulateStringDictionary
- PopulateMultipleThreatStringDictionary
- PopulateMalwareStringDictionary
- PopulatePhishingStringDictionary
- GetHTMLContents
- PopulateStringDictionary
- PopulateMultipleThreatStringDictionary
- PopulateMalwareStringDictionary
- PopulatePhishingStringDictionary
#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
#include <string>
#include "base/bind.h"
#include "base/i18n/rtl.h"
#include "base/lazy_instance.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_preferences_util.h"
#include "chrome/browser/safe_browsing/malware_details.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/escape.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
#include "ui/base/webui/web_ui_util.h"
using base::UserMetricsAction;
using content::BrowserThread;
using content::InterstitialPage;
using content::OpenURLParams;
using content::Referrer;
using content::WebContents;
namespace {
#if defined(GOOGLE_CHROME_BUILD)
const char* const kSbDiagnosticUrl =
"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=googlechrome";
#else
const char* const kSbDiagnosticUrl =
"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=chromium";
#endif
const char kSbReportPhishingErrorUrl[] =
"http://www.google.com/safebrowsing/report_error/";
const char kLearnMoreMalwareUrl[] =
"https://www.google.com/support/bin/answer.py?answer=45449&topic=360"
"&sa=X&oi=malwarewarninglink&resnum=1&ct=help";
const char kLearnMoreMalwareUrlV2[] =
"https://www.google.com/transparencyreport/safebrowsing/";
const char kLearnMorePhishingUrlV2[] =
"https://www.google.com/transparencyreport/safebrowsing/";
const char kLearnMorePhishingUrl[] =
"https://www.google.com/support/bin/answer.py?answer=106318";
const char kPrivacyLinkHtml[] =
"<a id=\"privacy-link\" href=\"\" onclick=\"sendCommand('showPrivacy'); "
"return false;\" onmousedown=\"return false;\">%s</a>";
const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000;
const char kShowDiagnosticCommand[] = "showDiagnostic";
const char kReportErrorCommand[] = "reportError";
const char kLearnMoreCommand[] = "learnMore";
const char kLearnMoreCommandV2[] = "learnMore2";
const char kShowPrivacyCommand[] = "showPrivacy";
const char kProceedCommand[] = "proceed";
const char kTakeMeBackCommand[] = "takeMeBack";
const char kDoReportCommand[] = "doReport";
const char kDontReportCommand[] = "dontReport";
const char kDisplayCheckBox[] = "displaycheckbox";
const char kBoxChecked[] = "boxchecked";
const char kExpandedSeeMore[] = "expandedSeeMore";
const char kNavigatedAwayMetaCommand[] = "closed";
base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap>
g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER;
const char kMalwareStudyName[] = "InterstitialMalware310";
const char kPhishingStudyName[] = "InterstitialPhishing564";
const char kCond7MalwareFearMsg[] = "cond7MalwareFearMsg";
const char kCond8PhishingFearMsg[] = "cond8PhishingFearMsg";
const char kCond9MalwareCollabMsg[] = "cond9MalwareCollabMsg";
const char kCond10PhishingCollabMsg[] = "cond10PhishingCollabMsg";
const char kCond11MalwareQuestion[] = "cond11MalwareQuestion";
const char kCond12PhishingQuestion[] = "cond12PhishingQuestion";
const char kCond13MalwareGoBack[] = "cond13MalwareGoBack";
const char kCond14PhishingGoBack[] = "cond14PhishingGoBack";
enum DetailedDecision {
MALWARE_SHOW_NEW_SITE = 0,
MALWARE_PROCEED_NEW_SITE,
MALWARE_SHOW_CROSS_SITE,
MALWARE_PROCEED_CROSS_SITE,
PHISHING_SHOW_NEW_SITE,
PHISHING_PROCEED_NEW_SITE,
PHISHING_SHOW_CROSS_SITE,
PHISHING_PROCEED_CROSS_SITE,
MAX_DETAILED_ACTION
};
void RecordDetailedUserAction(DetailedDecision decision) {
UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialActionDetails",
decision,
MAX_DETAILED_ACTION);
}
}
SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL;
class SafeBrowsingBlockingPageFactoryImpl
: public SafeBrowsingBlockingPageFactory {
public:
virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
SafeBrowsingUIManager* ui_manager,
WebContents* web_contents,
const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
OVERRIDE {
if (unsafe_resources.size() == 1 &&
(unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
unsafe_resources[0].threat_type ==
SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL ||
unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_PHISHING ||
unsafe_resources[0].threat_type ==
SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL)) {
return new SafeBrowsingBlockingPageV2(ui_manager, web_contents,
unsafe_resources);
}
return new SafeBrowsingBlockingPageV1(ui_manager, web_contents,
unsafe_resources);
}
private:
friend struct base::DefaultLazyInstanceTraits<
SafeBrowsingBlockingPageFactoryImpl>;
SafeBrowsingBlockingPageFactoryImpl() { }
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageFactoryImpl);
};
static base::LazyInstance<SafeBrowsingBlockingPageFactoryImpl>
g_safe_browsing_blocking_page_factory_impl = LAZY_INSTANCE_INITIALIZER;
SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
SafeBrowsingUIManager* ui_manager,
WebContents* web_contents,
const UnsafeResourceList& unsafe_resources)
: malware_details_proceed_delay_ms_(
kMalwareDetailsProceedDelayMilliSeconds),
ui_manager_(ui_manager),
report_loop_(NULL),
is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources)),
unsafe_resources_(unsafe_resources),
proceeded_(false),
web_contents_(web_contents),
url_(unsafe_resources[0].url),
has_expanded_see_more_section_(false),
num_visits_(-1) {
bool malware = false;
bool phishing = false;
for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
iter != unsafe_resources_.end(); ++iter) {
const UnsafeResource& resource = *iter;
SBThreatType threat_type = resource.threat_type;
if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
malware = true;
} else {
DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
phishing = true;
}
}
DCHECK(phishing || malware);
if (malware && phishing)
interstitial_type_ = TYPE_MALWARE_AND_PHISHING;
else if (malware)
interstitial_type_ = TYPE_MALWARE;
else
interstitial_type_ = TYPE_PHISHING;
RecordUserAction(SHOW);
HistoryService* history_service = HistoryServiceFactory::GetForProfile(
Profile::FromBrowserContext(web_contents->GetBrowserContext()),
Profile::EXPLICIT_ACCESS);
if (history_service) {
history_service->GetVisibleVisitCountToHost(
url_,
&request_consumer_,
base::Bind(&SafeBrowsingBlockingPage::OnGotHistoryCount,
base::Unretained(this)));
}
if (!is_main_frame_load_blocked_) {
navigation_entry_index_to_remove_ =
web_contents->GetController().GetLastCommittedEntryIndex();
} else {
navigation_entry_index_to_remove_ = -1;
}
if (unsafe_resources.size() == 1 &&
unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE &&
malware_details_.get() == NULL && CanShowMalwareDetailsOption()) {
malware_details_ = MalwareDetails::NewMalwareDetails(
ui_manager_, web_contents, unsafe_resources[0]);
}
interstitial_page_ = InterstitialPage::Create(
web_contents, IsMainPageLoadBlocked(unsafe_resources), url_, this);
}
bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() {
return (!web_contents_->GetBrowserContext()->IsOffTheRecord() &&
web_contents_->GetURL().SchemeIs(content::kHttpScheme));
}
SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() {
}
void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) {
std::string command(cmd);
if (command.length() > 1 && command[0] == '"') {
command = command.substr(1, command.length() - 2);
}
RecordUserReactionTime(command);
if (command == kDoReportCommand) {
SetReportingPreference(true);
return;
}
if (command == kDontReportCommand) {
SetReportingPreference(false);
return;
}
if (command == kLearnMoreCommand) {
GURL url;
SBThreatType threat_type = unsafe_resources_[0].threat_type;
if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrl));
} else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
url = google_util::AppendGoogleLocaleParam(GURL(kLearnMorePhishingUrl));
} else {
NOTREACHED();
}
OpenURLParams params(
url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
web_contents_->OpenURL(params);
return;
}
if (command == kLearnMoreCommandV2) {
GURL url;
SBThreatType threat_type = unsafe_resources_[0].threat_type;
if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrlV2));
} else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
url = google_util::AppendGoogleLocaleParam(GURL(kLearnMorePhishingUrlV2));
} else {
NOTREACHED();
}
OpenURLParams params(
url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
web_contents_->OpenURL(params);
return;
}
if (command == kShowPrivacyCommand) {
GURL url(l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL));
OpenURLParams params(
url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
web_contents_->OpenURL(params);
return;
}
bool proceed_blocked = false;
if (command == kProceedCommand) {
if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
proceed_blocked = true;
} else {
interstitial_page_->Proceed();
return;
}
}
if (command == kTakeMeBackCommand || proceed_blocked) {
if (is_main_frame_load_blocked_) {
interstitial_page_->DontProceed();
return;
}
if (web_contents_->GetController().CanGoBack()) {
web_contents_->GetController().GoBack();
} else {
web_contents_->GetController().LoadURL(
GURL(chrome::kChromeUINewTabURL),
content::Referrer(),
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
std::string());
}
return;
}
size_t element_index = 0;
size_t colon_index = command.find(':');
if (colon_index != std::string::npos) {
DCHECK(colon_index < command.size() - 1);
int result_int = 0;
bool result = base::StringToInt(base::StringPiece(command.begin() +
colon_index + 1,
command.end()),
&result_int);
command = command.substr(0, colon_index);
if (result)
element_index = static_cast<size_t>(result_int);
}
if (element_index >= unsafe_resources_.size()) {
NOTREACHED();
return;
}
std::string bad_url_spec = unsafe_resources_[element_index].url.spec();
if (command == kReportErrorCommand) {
SBThreatType threat_type = unsafe_resources_[element_index].threat_type;
DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
GURL report_url =
safe_browsing_util::GeneratePhishingReportUrl(
kSbReportPhishingErrorUrl,
bad_url_spec,
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
OpenURLParams params(
report_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
false);
web_contents_->OpenURL(params);
return;
}
if (command == kShowDiagnosticCommand) {
std::string diagnostic =
base::StringPrintf(kSbDiagnosticUrl,
net::EscapeQueryParamValue(bad_url_spec, true).c_str());
GURL diagnostic_url(diagnostic);
diagnostic_url = google_util::AppendGoogleLocaleParam(diagnostic_url);
DCHECK(unsafe_resources_[element_index].threat_type ==
SB_THREAT_TYPE_URL_MALWARE ||
unsafe_resources_[element_index].threat_type ==
SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL);
OpenURLParams params(
diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
false);
web_contents_->OpenURL(params);
return;
}
if (command == kExpandedSeeMore) {
return;
}
NOTREACHED() << "Unexpected command: " << command;
}
void SafeBrowsingBlockingPage::OverrideRendererPrefs(
content::RendererPreferences* prefs) {
Profile* profile = Profile::FromBrowserContext(
web_contents_->GetBrowserContext());
renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
}
void SafeBrowsingBlockingPage::SetReportingPreference(bool report) {
Profile* profile = Profile::FromBrowserContext(
web_contents_->GetBrowserContext());
PrefService* pref = profile->GetPrefs();
pref->SetBoolean(prefs::kSafeBrowsingReportingEnabled, report);
UMA_HISTOGRAM_BOOLEAN("SB2.SetReportingEnabled", report);
}
void SafeBrowsingBlockingPage::OnProceed() {
proceeded_ = true;
RecordUserAction(PROCEED);
FinishMalwareDetails(malware_details_proceed_delay_ms_);
NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, true);
UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
SafeBrowsingBlockingPage* blocking_page = NULL;
if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
blocking_page = factory_->CreateSafeBrowsingPage(ui_manager_, web_contents_,
iter->second);
unsafe_resource_map->erase(iter);
}
if (blocking_page)
blocking_page->interstitial_page_->Show();
}
void SafeBrowsingBlockingPage::OnDontProceed() {
RecordUserReactionTime(kNavigatedAwayMetaCommand);
if (proceeded_)
return;
RecordUserAction(DONT_PROCEED);
FinishMalwareDetails(0);
NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, false);
UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
NotifySafeBrowsingUIManager(ui_manager_, iter->second, false);
unsafe_resource_map->erase(iter);
}
int last_committed_index =
web_contents_->GetController().GetLastCommittedEntryIndex();
if (navigation_entry_index_to_remove_ != -1 &&
navigation_entry_index_to_remove_ != last_committed_index &&
!web_contents_->IsBeingDestroyed()) {
CHECK(web_contents_->GetController().RemoveEntryAtIndex(
navigation_entry_index_to_remove_));
navigation_entry_index_to_remove_ = -1;
}
}
void SafeBrowsingBlockingPage::OnGotHistoryCount(HistoryService::Handle handle,
bool success,
int num_visits,
base::Time first_visit) {
if (success)
num_visits_ = num_visits;
}
void SafeBrowsingBlockingPage::RecordUserAction(BlockingPageEvent event) {
enum {
MALWARE_SHOW = 0,
MALWARE_DONT_PROCEED,
MALWARE_FORCED_DONT_PROCEED,
MALWARE_PROCEED,
MULTIPLE_SHOW,
MULTIPLE_DONT_PROCEED,
MULTIPLE_FORCED_DONT_PROCEED,
MULTIPLE_PROCEED,
PHISHING_SHOW,
PHISHING_DONT_PROCEED,
PHISHING_FORCED_DONT_PROCEED,
PHISHING_PROCEED,
MALWARE_SHOW_ADVANCED,
MULTIPLE_SHOW_ADVANCED,
PHISHING_SHOW_ADVANCED,
MAX_ACTION
} histogram_action = MAX_ACTION;
switch (event) {
case SHOW:
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
histogram_action = MULTIPLE_SHOW;
break;
case TYPE_MALWARE:
histogram_action = MALWARE_SHOW;
break;
case TYPE_PHISHING:
histogram_action = PHISHING_SHOW;
break;
}
break;
case PROCEED:
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
histogram_action = MULTIPLE_PROCEED;
break;
case TYPE_MALWARE:
histogram_action = MALWARE_PROCEED;
break;
case TYPE_PHISHING:
histogram_action = PHISHING_PROCEED;
break;
}
break;
case DONT_PROCEED:
if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
histogram_action = MULTIPLE_FORCED_DONT_PROCEED;
break;
case TYPE_MALWARE:
histogram_action = MALWARE_FORCED_DONT_PROCEED;
break;
case TYPE_PHISHING:
histogram_action = PHISHING_FORCED_DONT_PROCEED;
break;
}
} else {
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
histogram_action = MULTIPLE_DONT_PROCEED;
break;
case TYPE_MALWARE:
histogram_action = MALWARE_DONT_PROCEED;
break;
case TYPE_PHISHING:
histogram_action = PHISHING_DONT_PROCEED;
break;
}
}
break;
case SHOW_ADVANCED:
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
histogram_action = MULTIPLE_SHOW_ADVANCED;
break;
case TYPE_MALWARE:
histogram_action = MALWARE_SHOW_ADVANCED;
break;
case TYPE_PHISHING:
histogram_action = PHISHING_SHOW_ADVANCED;
break;
}
break;
default:
NOTREACHED() << "Unexpected event: " << event;
}
if (histogram_action == MAX_ACTION) {
NOTREACHED();
} else {
UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialAction", histogram_action,
MAX_ACTION);
}
if (event == PROCEED || event == DONT_PROCEED) {
if (num_visits_ == 0 && interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
MALWARE_SHOW_NEW_SITE : PHISHING_SHOW_NEW_SITE);
if (event == PROCEED) {
RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
MALWARE_PROCEED_NEW_SITE : PHISHING_PROCEED_NEW_SITE);
}
}
if (unsafe_resources_[0].is_subresource &&
interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
MALWARE_SHOW_CROSS_SITE : PHISHING_SHOW_CROSS_SITE);
if (event == PROCEED) {
RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
MALWARE_PROCEED_CROSS_SITE : PHISHING_PROCEED_CROSS_SITE);
}
}
}
std::string action = "SBInterstitial";
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
action.append("Multiple");
break;
case TYPE_MALWARE:
action.append("Malware");
break;
case TYPE_PHISHING:
action.append("Phishing");
break;
}
switch (event) {
case SHOW:
action.append("Show");
break;
case PROCEED:
action.append("Proceed");
break;
case DONT_PROCEED:
if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled))
action.append("ForcedDontProceed");
else
action.append("DontProceed");
break;
case SHOW_ADVANCED:
break;
default:
NOTREACHED() << "Unexpected event: " << event;
}
content::RecordComputedAction(action);
}
void SafeBrowsingBlockingPage::RecordUserReactionTime(
const std::string& command) {
if (interstitial_show_time_.is_null())
return;
base::TimeDelta dt = base::TimeTicks::Now() - interstitial_show_time_;
DVLOG(1) << "User reaction time for command:" << command
<< " on interstitial_type_:" << interstitial_type_
<< " warning took " << dt.InMilliseconds() << "ms";
bool recorded = true;
if (interstitial_type_ == TYPE_MALWARE ||
interstitial_type_ == TYPE_MALWARE_AND_PHISHING) {
if (command == kProceedCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeProceed", dt);
} else if (command == kTakeMeBackCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeTakeMeBack", dt);
} else if (command == kShowDiagnosticCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeDiagnostic", dt);
} else if (command == kShowPrivacyCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimePrivacyPolicy",
dt);
} else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialLearnMore",
dt);
} else if (command == kNavigatedAwayMetaCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt);
} else if (command == kExpandedSeeMore) {
if (has_expanded_see_more_section_)
return;
RecordUserAction(SHOW_ADVANCED);
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore",
dt);
has_expanded_see_more_section_ = true;
recorded = false;
} else {
recorded = false;
}
} else {
if (command == kProceedCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt);
} else if (command == kTakeMeBackCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt);
} else if (command == kShowDiagnosticCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt);
} else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt);
} else if (command == kNavigatedAwayMetaCommand) {
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt);
} else if (command == kExpandedSeeMore) {
if (has_expanded_see_more_section_)
return;
RecordUserAction(SHOW_ADVANCED);
UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore",
dt);
has_expanded_see_more_section_ = true;
recorded = false;
} else {
recorded = false;
}
}
if (recorded)
interstitial_show_time_ = base::TimeTicks();
}
void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) {
if (malware_details_.get() == NULL)
return;
const bool enabled = IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled);
UMA_HISTOGRAM_BOOLEAN("SB2.ReportingIsEnabled", enabled);
if (enabled) {
BrowserThread::PostDelayedTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&MalwareDetails::FinishCollection, malware_details_.get()),
base::TimeDelta::FromMilliseconds(delay_ms));
}
}
bool SafeBrowsingBlockingPage::IsPrefEnabled(const char* pref) {
Profile* profile =
Profile::FromBrowserContext(web_contents_->GetBrowserContext());
return profile->GetPrefs()->GetBoolean(pref);
}
void SafeBrowsingBlockingPage::NotifySafeBrowsingUIManager(
SafeBrowsingUIManager* ui_manager,
const UnsafeResourceList& unsafe_resources,
bool proceed) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
ui_manager, unsafe_resources, proceed));
}
SafeBrowsingBlockingPage::UnsafeResourceMap*
SafeBrowsingBlockingPage::GetUnsafeResourcesMap() {
return g_unsafe_resource_map.Pointer();
}
void SafeBrowsingBlockingPage::ShowBlockingPage(
SafeBrowsingUIManager* ui_manager,
const UnsafeResource& unsafe_resource) {
DVLOG(1) << __FUNCTION__ << " " << unsafe_resource.url.spec();
WebContents* web_contents = tab_util::GetWebContentsByID(
unsafe_resource.render_process_host_id, unsafe_resource.render_view_id);
InterstitialPage* interstitial =
InterstitialPage::GetInterstitialPage(web_contents);
if (interstitial && !unsafe_resource.is_subresource) {
interstitial->DontProceed();
interstitial = NULL;
}
if (!interstitial) {
std::vector<UnsafeResource> resources;
resources.push_back(unsafe_resource);
if (!factory_)
factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer();
SafeBrowsingBlockingPage* blocking_page =
factory_->CreateSafeBrowsingPage(ui_manager, web_contents, resources);
blocking_page->interstitial_page_->Show();
return;
}
UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
(*unsafe_resource_map)[web_contents].push_back(unsafe_resource);
}
bool SafeBrowsingBlockingPage::IsMainPageLoadBlocked(
const UnsafeResourceList& unsafe_resources) {
if (unsafe_resources[0].threat_type ==
SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
return false;
}
return unsafe_resources.size() == 1 && !unsafe_resources[0].is_subresource;
}
SafeBrowsingBlockingPageV1::SafeBrowsingBlockingPageV1(
SafeBrowsingUIManager* ui_manager,
WebContents* web_contents,
const UnsafeResourceList& unsafe_resources)
: SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
}
std::string SafeBrowsingBlockingPageV1::GetHTMLContents() {
base::DictionaryValue strings;
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
std::string html;
if (unsafe_resources_.empty()) {
NOTREACHED();
return std::string();
}
DCHECK_GT(unsafe_resources_.size(), 1U);
PopulateMultipleThreatStringDictionary(&strings);
html = rb.GetRawDataResource(
IDR_SAFE_BROWSING_MULTIPLE_THREAT_BLOCK).as_string();
interstitial_show_time_ = base::TimeTicks::Now();
return webui::GetTemplatesHtml(html, &strings, "template_root");
}
void SafeBrowsingBlockingPageV1::PopulateStringDictionary(
base::DictionaryValue* strings,
const base::string16& title,
const base::string16& headline,
const base::string16& description1,
const base::string16& description2,
const base::string16& description3) {
strings->SetString("title", title);
strings->SetString("headLine", headline);
strings->SetString("description1", description1);
strings->SetString("description2", description2);
strings->SetString("description3", description3);
strings->SetBoolean("proceedDisabled",
IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
}
void SafeBrowsingBlockingPageV1::PopulateMultipleThreatStringDictionary(
base::DictionaryValue* strings) {
base::string16 malware_label =
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_LABEL);
base::string16 malware_link =
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_DIAGNOSTIC_PAGE);
base::string16 phishing_label =
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_LABEL);
base::string16 phishing_link =
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_REPORT_ERROR);
base::ListValue* error_strings = new base::ListValue;
for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
iter != unsafe_resources_.end(); ++iter) {
const UnsafeResource& resource = *iter;
SBThreatType threat_type = resource.threat_type;
base::DictionaryValue* current_error_strings = new base::DictionaryValue;
if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
current_error_strings->SetString("type", "malware");
current_error_strings->SetString("typeLabel", malware_label);
current_error_strings->SetString("errorLink", malware_link);
} else {
DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
current_error_strings->SetString("type", "phishing");
current_error_strings->SetString("typeLabel", phishing_label);
current_error_strings->SetString("errorLink", phishing_link);
}
current_error_strings->SetString("url", resource.url.spec());
error_strings->Append(current_error_strings);
}
strings->Set("errors", error_strings);
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
PopulateStringDictionary(
strings,
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MULTI_THREAT_TITLE),
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION1,
base::UTF8ToUTF16(web_contents_->GetURL().host())),
l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION2),
base::string16());
break;
case TYPE_MALWARE:
PopulateStringDictionary(
strings,
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_TITLE),
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION1,
base::UTF8ToUTF16(web_contents_->GetURL().host())),
l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION2),
l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION3));
break;
case TYPE_PHISHING:
PopulateStringDictionary(
strings,
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_TITLE),
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_HEADLINE),
l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MULTI_PHISHING_DESCRIPTION1,
base::UTF8ToUTF16(web_contents_->GetURL().host())),
base::string16(),
base::string16());
break;
}
strings->SetString("confirm_text",
l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION_AGREE));
strings->SetString("continue_button",
l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MULTI_MALWARE_PROCEED_BUTTON));
strings->SetString("back_button",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
strings->SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
}
void SafeBrowsingBlockingPageV1::PopulateMalwareStringDictionary(
base::DictionaryValue* strings) {
NOTREACHED();
}
void SafeBrowsingBlockingPageV1::PopulatePhishingStringDictionary(
base::DictionaryValue* strings) {
NOTREACHED();
}
SafeBrowsingBlockingPageV2::SafeBrowsingBlockingPageV2(
SafeBrowsingUIManager* ui_manager,
WebContents* web_contents,
const UnsafeResourceList& unsafe_resources)
: SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
if (unsafe_resources_[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
unsafe_resources_[0].threat_type ==
SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
trialCondition_ =
base::FieldTrialList::FindFullName(kMalwareStudyName);
} else if (unsafe_resources_[0].threat_type ==
SB_THREAT_TYPE_URL_PHISHING ||
unsafe_resources_[0].threat_type ==
SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
trialCondition_ =
base::FieldTrialList::FindFullName(kPhishingStudyName);
}
}
std::string SafeBrowsingBlockingPageV2::GetHTMLContents() {
base::DictionaryValue strings;
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
std::string html;
if (unsafe_resources_.empty()) {
NOTREACHED();
return std::string();
}
if (unsafe_resources_.size() > 1) {
NOTREACHED();
} else {
SBThreatType threat_type = unsafe_resources_[0].threat_type;
if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
PopulateMalwareStringDictionary(&strings);
} else {
DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
PopulatePhishingStringDictionary(&strings);
}
html = rb.GetRawDataResource(IDR_SAFE_BROWSING_MALWARE_BLOCK_V2).
as_string();
}
interstitial_show_time_ = base::TimeTicks::Now();
return webui::GetTemplatesHtml(html, &strings, "template-root");
}
void SafeBrowsingBlockingPageV2::PopulateStringDictionary(
base::DictionaryValue* strings,
const base::string16& title,
const base::string16& headline,
const base::string16& description1,
const base::string16& description2,
const base::string16& description3) {
strings->SetString("title", title);
strings->SetString("headLine", headline);
strings->SetString("description1", description1);
strings->SetString("description2", description2);
strings->SetString("description3", description3);
strings->SetBoolean("proceedDisabled",
IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
strings->SetBoolean("isMainFrame", is_main_frame_load_blocked_);
strings->SetBoolean("isPhishing", interstitial_type_ == TYPE_PHISHING);
strings->SetString("back_button",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
strings->SetString("seeMore", l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE));
strings->SetString("proceed",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK));
strings->SetString("trialType", trialCondition_);
if (trialCondition_ == kCond7MalwareFearMsg) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_FEAR_HEADLINE));
} else if (trialCondition_ == kCond8PhishingFearMsg) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_FEAR_HEADLINE));
} else if (trialCondition_ == kCond9MalwareCollabMsg) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_COLLAB_HEADLINE));
} else if (trialCondition_ == kCond10PhishingCollabMsg) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_COLLAB_HEADLINE));
} else if (trialCondition_ == kCond11MalwareQuestion) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_QUESTION_HEADLINE));
} else if (trialCondition_ == kCond12PhishingQuestion) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_PHISHING_QUESTION_HEADLINE));
} else if (trialCondition_ == kCond13MalwareGoBack) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_HEADLINE));
} else if (trialCondition_ == kCond14PhishingGoBack) {
strings->SetString("headLine",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_BACK_HEADLINE));
}
webui::SetFontAndTextDirection(strings);
}
void SafeBrowsingBlockingPageV2::PopulateMultipleThreatStringDictionary(
base::DictionaryValue* strings) {
NOTREACHED();
}
void SafeBrowsingBlockingPageV2::PopulateMalwareStringDictionary(
base::DictionaryValue* strings) {
base::string16 headline, description1, description2, description3;
description3 = l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION3);
if (is_main_frame_load_blocked_) {
headline = l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE);
description1 = l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1,
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
base::UTF8ToUTF16(url_.host()));
description2 = l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2);
strings->SetString("details", l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_DETAILS));
} else {
headline = l10n_util::GetStringUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE_SUBRESOURCE);
description1 = l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1_SUBRESOURCE,
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
base::UTF8ToUTF16(web_contents_->GetURL().host()));
description2 = l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2_SUBRESOURCE,
base::UTF8ToUTF16(url_.host()));
strings->SetString("details", l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_DETAILS_SUBRESOURCE,
base::UTF8ToUTF16(url_.host())));
}
PopulateStringDictionary(
strings,
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_TITLE),
headline,
description1,
description2,
description3);
if (!CanShowMalwareDetailsOption()) {
strings->SetBoolean(kDisplayCheckBox, false);
strings->SetString("confirm_text", std::string());
strings->SetString(kBoxChecked, std::string());
} else {
strings->SetBoolean(kDisplayCheckBox, true);
std::string privacy_link = base::StringPrintf(
kPrivacyLinkHtml,
l10n_util::GetStringUTF8(
IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE_V2).c_str());
strings->SetString("confirm_text",
l10n_util::GetStringFUTF16(
IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE,
base::UTF8ToUTF16(privacy_link)));
if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled))
strings->SetString(kBoxChecked, "yes");
else
strings->SetString(kBoxChecked, std::string());
}
strings->SetString("report_error", base::string16());
strings->SetString("learnMore",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
}
void SafeBrowsingBlockingPageV2::PopulatePhishingStringDictionary(
base::DictionaryValue* strings) {
PopulateStringDictionary(
strings,
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_TITLE),
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_HEADLINE),
l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION1,
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
base::UTF8ToUTF16(url_.host())),
base::string16(),
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION2));
strings->SetString("details", std::string());
strings->SetString("confirm_text", std::string());
strings->SetString(kBoxChecked, std::string());
strings->SetString(
"report_error",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_REPORT_ERROR));
strings->SetBoolean(kDisplayCheckBox, false);
strings->SetString("learnMore",
l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
}