OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/safe_browsing/base_ui_manager.h" | 5 #include "components/safe_browsing/base_ui_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/macros.h" | 9 #include "base/i18n/rtl.h" |
| 10 #include "base/metrics/histogram_macros.h" |
| 11 #include "base/supports_user_data.h" |
| 12 #include "components/safe_browsing/base_blocking_page.h" |
10 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
11 #include "content/public/browser/navigation_entry.h" | 14 #include "content/public/browser/navigation_entry.h" |
12 #include "content/public/browser/web_contents.h" | 15 #include "content/public/browser/web_contents.h" |
13 | 16 |
14 using content::BrowserThread; | 17 using content::BrowserThread; |
15 using content::NavigationEntry; | 18 using content::NavigationEntry; |
16 using content::WebContents; | 19 using content::WebContents; |
17 using safe_browsing::HitReport; | 20 using safe_browsing::HitReport; |
18 using safe_browsing::SBThreatType; | 21 using safe_browsing::SBThreatType; |
19 | 22 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 site_list = new WhitelistUrlSet; | 88 site_list = new WhitelistUrlSet; |
86 web_contents->SetUserData(kWhitelistKey, site_list); | 89 web_contents->SetUserData(kWhitelistKey, site_list); |
87 } | 90 } |
88 return site_list; | 91 return site_list; |
89 } | 92 } |
90 | 93 |
91 } // namespace | 94 } // namespace |
92 | 95 |
93 namespace safe_browsing { | 96 namespace safe_browsing { |
94 | 97 |
95 BaseSafeBrowsingUIManager::BaseSafeBrowsingUIManager() {} | 98 BaseUIManager::BaseUIManager() {} |
96 | 99 |
97 void BaseSafeBrowsingUIManager::StopOnIOThread(bool shutdown) { | 100 void BaseUIManager::StopOnIOThread(bool shutdown) { |
98 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 101 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
99 // TODO(ntfschr): implement this once SafeBrowsingService is componentized | 102 // TODO(ntfschr): implement this once SafeBrowsingService is componentized |
100 return; | 103 return; |
101 } | 104 } |
102 | 105 |
103 BaseSafeBrowsingUIManager::~BaseSafeBrowsingUIManager() {} | 106 BaseUIManager::~BaseUIManager() {} |
104 | 107 |
105 bool BaseSafeBrowsingUIManager::IsWhitelisted(const UnsafeResource& resource) { | 108 bool BaseUIManager::IsWhitelisted(const UnsafeResource& resource) { |
106 NavigationEntry* entry = nullptr; | 109 NavigationEntry* entry = nullptr; |
107 if (resource.is_subresource) { | 110 if (resource.is_subresource) { |
108 entry = resource.GetNavigationEntryForResource(); | 111 entry = resource.GetNavigationEntryForResource(); |
109 } | 112 } |
110 SBThreatType unused_threat_type; | 113 SBThreatType unused_threat_type; |
111 return IsUrlWhitelistedOrPendingForWebContents( | 114 return IsUrlWhitelistedOrPendingForWebContents( |
112 resource.url, resource.is_subresource, entry, | 115 resource.url, resource.is_subresource, entry, |
113 resource.web_contents_getter.Run(), true, &unused_threat_type); | 116 resource.web_contents_getter.Run(), true, &unused_threat_type); |
114 } | 117 } |
115 | 118 |
116 // Check if the user has already seen and/or ignored a SB warning for this | 119 // Check if the user has already seen and/or ignored a SB warning for this |
117 // WebContents and top-level domain. | 120 // WebContents and top-level domain. |
118 bool BaseSafeBrowsingUIManager::IsUrlWhitelistedOrPendingForWebContents( | 121 bool BaseUIManager::IsUrlWhitelistedOrPendingForWebContents( |
119 const GURL& url, | 122 const GURL& url, |
120 bool is_subresource, | 123 bool is_subresource, |
121 NavigationEntry* entry, | 124 NavigationEntry* entry, |
122 WebContents* web_contents, | 125 WebContents* web_contents, |
123 bool whitelist_only, | 126 bool whitelist_only, |
124 SBThreatType* threat_type) { | 127 SBThreatType* threat_type) { |
125 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 128 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
126 | 129 |
127 GURL lookup_url = GetWhitelistUrl(url, is_subresource, entry); | 130 GURL lookup_url = GetWhitelistUrl(url, is_subresource, entry); |
128 if (lookup_url.is_empty()) | 131 if (lookup_url.is_empty()) |
129 return false; | 132 return false; |
130 | 133 |
131 WhitelistUrlSet* site_list = | 134 WhitelistUrlSet* site_list = |
132 static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); | 135 static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); |
133 if (!site_list) | 136 if (!site_list) |
134 return false; | 137 return false; |
135 | 138 |
136 bool whitelisted = site_list->Contains(lookup_url, threat_type); | 139 bool whitelisted = site_list->Contains(lookup_url, threat_type); |
137 if (whitelist_only) { | 140 if (whitelist_only) { |
138 return whitelisted; | 141 return whitelisted; |
139 } else { | 142 } else { |
140 return whitelisted || site_list->ContainsPending(lookup_url, threat_type); | 143 return whitelisted || site_list->ContainsPending(lookup_url, threat_type); |
141 } | 144 } |
142 } | 145 } |
143 | 146 |
144 void BaseSafeBrowsingUIManager::OnBlockingPageDone( | 147 void BaseUIManager::OnBlockingPageDone( |
145 const std::vector<UnsafeResource>& resources, | 148 const std::vector<UnsafeResource>& resources, |
146 bool proceed, | 149 bool proceed, |
147 WebContents* web_contents, | 150 WebContents* web_contents, |
148 const GURL& main_frame_url) { | 151 const GURL& main_frame_url) { |
149 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 152 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
150 for (const auto& resource : resources) { | 153 for (const auto& resource : resources) { |
151 if (!resource.callback.is_null()) { | 154 if (!resource.callback.is_null()) { |
152 DCHECK(resource.callback_thread); | 155 DCHECK(resource.callback_thread); |
153 resource.callback_thread->PostTask( | 156 resource.callback_thread->PostTask( |
154 FROM_HERE, base::Bind(resource.callback, proceed)); | 157 FROM_HERE, base::Bind(resource.callback, proceed)); |
155 } | 158 } |
156 | 159 |
157 GURL whitelist_url = GetWhitelistUrl( | 160 GURL whitelist_url = GetWhitelistUrl( |
158 main_frame_url, false /* is subresource */, | 161 main_frame_url, false /* is subresource */, |
159 nullptr /* no navigation entry needed for main resource */); | 162 nullptr /* no navigation entry needed for main resource */); |
160 if (proceed) { | 163 if (proceed) { |
161 AddToWhitelistUrlSet(whitelist_url, web_contents, | 164 AddToWhitelistUrlSet(whitelist_url, web_contents, |
162 false /* Pending -> permanent */, | 165 false /* Pending -> permanent */, |
163 resource.threat_type); | 166 resource.threat_type); |
164 } else if (web_contents) { | 167 } else if (web_contents) { |
165 // |web_contents| doesn't exist if the tab has been closed. | 168 // |web_contents| doesn't exist if the tab has been closed. |
166 RemoveFromPendingWhitelistUrlSet(whitelist_url, web_contents); | 169 RemoveFromPendingWhitelistUrlSet(whitelist_url, web_contents); |
167 } | 170 } |
168 } | 171 } |
169 } | 172 } |
170 | 173 |
171 void BaseSafeBrowsingUIManager::DisplayBlockingPage( | 174 void BaseUIManager::DisplayBlockingPage( |
172 const UnsafeResource& resource) { | 175 const UnsafeResource& resource) { |
173 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 176 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
174 // TODO(ntfschr): implement this once SafeBrowsingBlockingPage is | 177 if (resource.is_subresource && !resource.is_subframe) { |
175 // componentized | 178 // Sites tagged as serving Unwanted Software should only show a warning for |
176 return; | 179 // main-frame or sub-frame resource. Similar warning restrictions should be |
| 180 // applied to malware sites tagged as "landing sites" (see "Types of |
| 181 // Malware sites" under |
| 182 // https://developers.google.com/safe-browsing/developers_guide_v3#UserWarni
ngs). |
| 183 if (resource.threat_type == SB_THREAT_TYPE_URL_UNWANTED || |
| 184 (resource.threat_type == SB_THREAT_TYPE_URL_MALWARE && |
| 185 resource.threat_metadata.threat_pattern_type == |
| 186 ThreatPatternType::MALWARE_LANDING)) { |
| 187 if (!resource.callback.is_null()) { |
| 188 DCHECK(resource.callback_thread); |
| 189 resource.callback_thread->PostTask(FROM_HERE, |
| 190 base::Bind(resource.callback, true)); |
| 191 } |
| 192 |
| 193 return; |
| 194 } |
| 195 } |
| 196 |
| 197 // The tab might have been closed. If it was closed, just act as if "Don't |
| 198 // Proceed" had been chosen. |
| 199 WebContents* web_contents = resource.web_contents_getter.Run(); |
| 200 if (!web_contents) { |
| 201 OnBlockingPageDone(std::vector<UnsafeResource>{resource}, |
| 202 false /* proceed */, |
| 203 web_contents, |
| 204 GetMainFrameWhitelistUrlForResource(resource)); |
| 205 return; |
| 206 } |
| 207 |
| 208 // Check if the user has already ignored a SB warning for the same WebContents |
| 209 // and top-level domain. |
| 210 if (IsWhitelisted(resource)) { |
| 211 if (!resource.callback.is_null()) { |
| 212 DCHECK(resource.callback_thread); |
| 213 resource.callback_thread->PostTask(FROM_HERE, |
| 214 base::Bind(resource.callback, true)); |
| 215 } |
| 216 return; |
| 217 } |
| 218 |
| 219 // BaseUIManager does not send SafeBrowsingHitReport. Subclasses should |
| 220 // implement the reporting logic themselves if needed. |
| 221 AddToWhitelistUrlSet(GetMainFrameWhitelistUrlForResource(resource), |
| 222 resource.web_contents_getter.Run(), |
| 223 true /* A decision is now pending */, |
| 224 resource.threat_type); |
| 225 BaseBlockingPage::ShowBlockingPage(this, resource); |
177 } | 226 } |
178 | 227 |
179 void BaseSafeBrowsingUIManager::EnsureWhitelistCreated( | 228 void BaseUIManager::EnsureWhitelistCreated( |
180 WebContents* web_contents) { | 229 WebContents* web_contents) { |
181 GetOrCreateWhitelist(web_contents); | 230 GetOrCreateWhitelist(web_contents); |
182 } | 231 } |
183 | 232 |
184 void BaseSafeBrowsingUIManager::LogPauseDelay(base::TimeDelta time) { | 233 void BaseUIManager::LogPauseDelay(base::TimeDelta time) { |
| 234 UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time); |
185 return; | 235 return; |
186 } | 236 } |
187 | 237 |
188 // A safebrowsing hit is sent after a blocking page for malware/phishing | 238 // A safebrowsing hit is sent after a blocking page for malware/phishing |
189 // or after the warning dialog for download urls, only for | 239 // or after the warning dialog for download urls, only for |
190 // UMA || extended_reporting users. | 240 // UMA || extended_reporting users. |
191 void BaseSafeBrowsingUIManager::MaybeReportSafeBrowsingHit( | 241 void BaseUIManager::MaybeReportSafeBrowsingHit( |
192 const HitReport& hit_report) { | 242 const HitReport& hit_report) { |
193 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 243 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
194 // TODO(ntfschr): implement this once we support reporting in WebView | 244 // TODO(ntfschr): implement this once we support reporting in WebView |
195 return; | 245 return; |
196 } | 246 } |
197 | 247 |
198 void BaseSafeBrowsingUIManager::ReportSafeBrowsingHitOnIOThread( | 248 void BaseUIManager::ReportSafeBrowsingHitOnIOThread( |
199 const HitReport& hit_report) { | 249 const HitReport& hit_report) { |
200 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 250 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
201 // TODO(ntfschr): implement this once we support reporting in WebView | 251 // TODO(ntfschr): implement this once we support reporting in WebView |
202 return; | 252 return; |
203 } | 253 } |
204 | 254 |
205 // If the user had opted-in to send ThreatDetails, this gets called | 255 // If the user had opted-in to send ThreatDetails, this gets called |
206 // when the report is ready. | 256 // when the report is ready. |
207 void BaseSafeBrowsingUIManager::SendSerializedThreatDetails( | 257 void BaseUIManager::SendSerializedThreatDetails( |
208 const std::string& serialized) { | 258 const std::string& serialized) { |
209 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 259 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
210 // TODO(ntfschr): implement this once we support reporting in WebView | 260 // TODO(ntfschr): implement this once we support reporting in WebView |
211 return; | 261 return; |
212 } | 262 } |
213 | 263 |
214 // Record this domain in the given WebContents as either whitelisted or | 264 // Record this domain in the given WebContents as either whitelisted or |
215 // pending whitelisting (if an interstitial is currently displayed). If an | 265 // pending whitelisting (if an interstitial is currently displayed). If an |
216 // existing WhitelistUrlSet does not yet exist, create a new WhitelistUrlSet. | 266 // existing WhitelistUrlSet does not yet exist, create a new WhitelistUrlSet. |
217 void BaseSafeBrowsingUIManager::AddToWhitelistUrlSet(const GURL& whitelist_url, | 267 void BaseUIManager::AddToWhitelistUrlSet(const GURL& whitelist_url, |
218 WebContents* web_contents, | 268 WebContents* web_contents, |
219 bool pending, | 269 bool pending, |
220 SBThreatType threat_type) { | 270 SBThreatType threat_type) { |
221 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 271 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
222 | 272 |
223 // A WebContents might not exist if the tab has been closed. | 273 // A WebContents might not exist if the tab has been closed. |
224 if (!web_contents) | 274 if (!web_contents) |
225 return; | 275 return; |
226 | 276 |
227 WhitelistUrlSet* site_list = GetOrCreateWhitelist(web_contents); | 277 WhitelistUrlSet* site_list = GetOrCreateWhitelist(web_contents); |
228 | 278 |
229 if (whitelist_url.is_empty()) | 279 if (whitelist_url.is_empty()) |
230 return; | 280 return; |
231 | 281 |
232 if (pending) { | 282 if (pending) { |
233 site_list->InsertPending(whitelist_url, threat_type); | 283 site_list->InsertPending(whitelist_url, threat_type); |
234 } else { | 284 } else { |
235 site_list->Insert(whitelist_url, threat_type); | 285 site_list->Insert(whitelist_url, threat_type); |
236 } | 286 } |
237 | 287 |
238 // Notify security UI that security state has changed. | 288 // Notify security UI that security state has changed. |
239 web_contents->DidChangeVisibleSecurityState(); | 289 web_contents->DidChangeVisibleSecurityState(); |
240 } | 290 } |
241 | 291 |
242 void BaseSafeBrowsingUIManager::AddObserver(Observer* observer) { | 292 const std::string BaseUIManager::app_locale() const { |
243 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 293 return base::i18n::GetConfiguredLocale(); |
244 observer_list_.AddObserver(observer); | |
245 } | 294 } |
246 | 295 |
247 void BaseSafeBrowsingUIManager::RemoveObserver(Observer* observer) { | 296 history::HistoryService* BaseUIManager::history_service( |
248 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 297 content::WebContents* web_contents) { |
249 observer_list_.RemoveObserver(observer); | 298 // TODO(jialiul): figure out how to get HistoryService from webview. |
| 299 return nullptr; |
250 } | 300 } |
251 | 301 |
252 void BaseSafeBrowsingUIManager::RemoveFromPendingWhitelistUrlSet( | 302 const GURL BaseUIManager::default_safe_page() const { |
| 303 return GURL(url::kAboutBlankURL); |
| 304 } |
| 305 |
| 306 void BaseUIManager::RemoveFromPendingWhitelistUrlSet( |
253 const GURL& whitelist_url, | 307 const GURL& whitelist_url, |
254 WebContents* web_contents) { | 308 WebContents* web_contents) { |
255 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 309 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
256 | 310 |
257 // A WebContents might not exist if the tab has been closed. | 311 // A WebContents might not exist if the tab has been closed. |
258 if (!web_contents) | 312 if (!web_contents) |
259 return; | 313 return; |
260 | 314 |
261 // Use |web_contents| rather than |resource.web_contents_getter| | 315 // Use |web_contents| rather than |resource.web_contents_getter| |
262 // here. By this point, a "Back" navigation could have already been | 316 // here. By this point, a "Back" navigation could have already been |
(...skipping 16 matching lines...) Expand all Loading... |
279 // remove the main-frame URL from the pending whitelist, so the | 333 // remove the main-frame URL from the pending whitelist, so the |
280 // main-frame URL will have already been removed when the subsequent | 334 // main-frame URL will have already been removed when the subsequent |
281 // blocking pages are dismissed. | 335 // blocking pages are dismissed. |
282 if (site_list->ContainsPending(whitelist_url, nullptr)) | 336 if (site_list->ContainsPending(whitelist_url, nullptr)) |
283 site_list->RemovePending(whitelist_url); | 337 site_list->RemovePending(whitelist_url); |
284 | 338 |
285 // Notify security UI that security state has changed. | 339 // Notify security UI that security state has changed. |
286 web_contents->DidChangeVisibleSecurityState(); | 340 web_contents->DidChangeVisibleSecurityState(); |
287 } | 341 } |
288 | 342 |
| 343 // static |
| 344 GURL BaseUIManager::GetMainFrameWhitelistUrlForResource( |
| 345 const security_interstitials::UnsafeResource& resource) { |
| 346 if (resource.is_subresource) { |
| 347 NavigationEntry* entry = resource.GetNavigationEntryForResource(); |
| 348 if (!entry) |
| 349 return GURL(); |
| 350 return entry->GetURL().GetWithEmptyPath(); |
| 351 } |
| 352 return resource.url.GetWithEmptyPath(); |
| 353 } |
| 354 |
289 } // namespace safe_browsing | 355 } // namespace safe_browsing |
OLD | NEW |