Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(250)

Side by Side Diff: chrome/browser/permissions/permission_context_base.cc

Issue 2555913002: Implement origin specific Permissions Blacklisting. (Closed)
Patch Set: Fixing indentation. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/permissions/permission_context_base.h" 5 #include "chrome/browser/permissions/permission_context_base.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8
9 #include <set>
10 #include <string>
8 #include <utility> 11 #include <utility>
9 12
10 #include "base/callback.h" 13 #include "base/callback.h"
11 #include "base/logging.h" 14 #include "base/logging.h"
12 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/memory/weak_ptr.h"
13 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/timer/timer.h"
14 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 21 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
16 #include "chrome/browser/permissions/permission_decision_auto_blocker.h" 22 #include "chrome/browser/permissions/permission_decision_auto_blocker.h"
17 #include "chrome/browser/permissions/permission_request.h" 23 #include "chrome/browser/permissions/permission_request.h"
18 #include "chrome/browser/permissions/permission_request_id.h" 24 #include "chrome/browser/permissions/permission_request_id.h"
19 #include "chrome/browser/permissions/permission_request_impl.h" 25 #include "chrome/browser/permissions/permission_request_impl.h"
20 #include "chrome/browser/permissions/permission_request_manager.h" 26 #include "chrome/browser/permissions/permission_request_manager.h"
21 #include "chrome/browser/permissions/permission_uma_util.h" 27 #include "chrome/browser/permissions/permission_uma_util.h"
22 #include "chrome/browser/permissions/permission_util.h" 28 #include "chrome/browser/permissions/permission_util.h"
23 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
31 #include "chrome/common/chrome_features.h"
24 #include "chrome/common/pref_names.h" 32 #include "chrome/common/pref_names.h"
25 #include "components/content_settings/core/browser/host_content_settings_map.h" 33 #include "components/content_settings/core/browser/host_content_settings_map.h"
26 #include "components/content_settings/core/browser/website_settings_registry.h" 34 #include "components/content_settings/core/browser/website_settings_registry.h"
27 #include "components/prefs/pref_service.h" 35 #include "components/prefs/pref_service.h"
36 #include "components/safe_browsing_db/database_manager.h"
28 #include "components/variations/variations_associated_data.h" 37 #include "components/variations/variations_associated_data.h"
29 #include "content/public/browser/browser_thread.h" 38 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/render_frame_host.h" 39 #include "content/public/browser/render_frame_host.h"
31 #include "content/public/browser/web_contents.h" 40 #include "content/public/browser/web_contents.h"
41 #include "content/public/browser/web_contents_observer.h"
32 #include "content/public/common/origin_util.h" 42 #include "content/public/common/origin_util.h"
33 #include "url/gurl.h" 43 #include "url/gurl.h"
34 44
35 #if defined(OS_ANDROID) 45 #if defined(OS_ANDROID)
36 #include "chrome/browser/permissions/permission_queue_controller.h" 46 #include "chrome/browser/permissions/permission_queue_controller.h"
37 #endif 47 #endif
38 48
39 // static 49 // static
40 const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] = 50 const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] =
41 "PermissionsKillSwitch"; 51 "PermissionsKillSwitch";
42 // static 52 // static
43 const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] = 53 const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] =
44 "blocked"; 54 "blocked";
55 // Maximum time in milliseconds to wait for safe browsing service to check a
56 // url for blacklisting. After this amount of time, the check will be aborted
57 // and the url will be treated as not blacklisted.
58 const int kCheckUrlTimeoutMs = 1000;
59
60 // The client used when checking whether a permission has been blacklisted by
61 // Safe Browsing. The check is done asynchronously as no state can be stored in
62 // PermissionContextBase while it is in flight (since additional permission
63 // requests may be made). Hence, the client is heap allocated and is responsible
64 // for deleting itself when it is finished. Associated with a particular
65 // WebContents, so it can still delete itself when the WebContents is destroyed.
66 // A weak pointer factory is used to generate 'this' pointers for callbacks.
67 class PermissionsBlacklistSBClientImpl
68 : public safe_browsing::SafeBrowsingDatabaseManager::Client,
69 public content::WebContentsObserver {
70 public:
71 static void CheckSafeBrowsingBlacklist(
72 content::PermissionType permission_type,
73 const GURL& request_origin,
74 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
75 content::WebContents* web_contents,
76 base::Callback<void(bool)> callback) {
77 new PermissionsBlacklistSBClientImpl(permission_type, request_origin,
78 db_manager, web_contents, callback);
79 }
80
81 private:
82 PermissionsBlacklistSBClientImpl(
83 content::PermissionType permission_type,
84 const GURL& request_origin,
85 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
86 content::WebContents* web_contents,
87 base::Callback<void(bool)> callback)
88 : content::WebContentsObserver(web_contents),
89 permission_type_(permission_type),
90 callback_(callback),
91 weak_ptr_factory_(this) {
92 content::BrowserThread::PostTask(
93 content::BrowserThread::IO, FROM_HERE,
94 base::Bind(&PermissionsBlacklistSBClientImpl::StartCheck,
95 weak_ptr_factory_.GetWeakPtr(), db_manager, request_origin));
96 }
97
98 ~PermissionsBlacklistSBClientImpl() override {}
99
100 void StartCheck(
101 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
102 const GURL& request_origin) {
103 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
104 // Start the timer to interrupt into the client callback method with an
105 // empty response if Safe Browsing times out.
106 safe_browsing::ThreatMetadata empty_metadata;
107 timer_.Start(
108 FROM_HERE, base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs),
109 base::Bind(
110 &PermissionsBlacklistSBClientImpl::OnCheckApiBlacklistUrlResult,
111 weak_ptr_factory_.GetWeakPtr(), request_origin, empty_metadata));
112 db_manager->CheckApiBlacklistUrl(request_origin, this);
113 }
114
115 // SafeBrowsingDatabaseManager::Client implementation.
116 void OnCheckApiBlacklistUrlResult(
117 const GURL& url,
118 const safe_browsing::ThreatMetadata& metadata) override {
119 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
120 weak_ptr_factory_.InvalidateWeakPtrs();
121 bool permission_blocked =
122 metadata.api_permissions.find(PermissionUtil::GetPermissionString(
123 permission_type_)) != metadata.api_permissions.end();
124 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
125 base::Bind(callback_, permission_blocked));
126 // The result has been received, so the object can now delete itself.
127 delete this;
128 }
129
130 // WebContentsObserver implementation. WebContents should outlive the
131 // permission request, however if it doesn't, this will ensure the object
132 // is still freed properly.
133 void WebContentsDestroyed() override { delete this; }
134
135 content::PermissionType permission_type_;
136 base::Callback<void(bool)> callback_;
137 // Timer to abort the Safe Browsing check if it takes too long.
138 base::OneShotTimer timer_;
139 // Note: Factory remains last member so it is destroyed and any weak
140 // pointers invalidated before other members are destroyed.
141 base::WeakPtrFactory<PermissionsBlacklistSBClientImpl> weak_ptr_factory_;
dominickn 2016/12/15 03:52:45 Nit: DISALLOW_COPY_AND_ASSIGN here.
meredithl 2016/12/15 04:15:34 Done.
142 };
45 143
46 PermissionContextBase::PermissionContextBase( 144 PermissionContextBase::PermissionContextBase(
47 Profile* profile, 145 Profile* profile,
48 const content::PermissionType permission_type, 146 const content::PermissionType permission_type,
49 const ContentSettingsType content_settings_type) 147 const ContentSettingsType content_settings_type)
50 : profile_(profile), 148 : profile_(profile),
51 permission_type_(permission_type), 149 permission_type_(permission_type),
52 content_settings_type_(content_settings_type), 150 content_settings_type_(content_settings_type),
53 weak_factory_(this) { 151 weak_factory_(this) {
54 #if defined(OS_ANDROID) 152 #if defined(OS_ANDROID)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 192
95 DVLOG(1) << "Attempt to use " << type_name 193 DVLOG(1) << "Attempt to use " << type_name
96 << " from an invalid URL: " << requesting_origin << "," 194 << " from an invalid URL: " << requesting_origin << ","
97 << embedding_origin << " (" << type_name 195 << embedding_origin << " (" << type_name
98 << " is not supported in popups)"; 196 << " is not supported in popups)";
99 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, 197 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
100 false /* persist */, CONTENT_SETTING_BLOCK); 198 false /* persist */, CONTENT_SETTING_BLOCK);
101 return; 199 return;
102 } 200 }
103 201
202 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager =
203 GetSafeBrowsingDatabaseManager();
204 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) &&
205 database_manager) {
206 // The client will contact Safe Browsing, and invoke the callback with the
207 // result. This object will be freed once Safe Browsing has returned the
208 // results or timed out.
209 PermissionsBlacklistSBClientImpl::CheckSafeBrowsingBlacklist(
210 permission_type_, requesting_origin, database_manager, web_contents,
211 base::Bind(&PermissionContextBase::CheckPermissionsBlacklistResult,
212 base::Unretained(this), web_contents, id, requesting_origin,
213 embedding_origin, user_gesture, callback));
214 } else {
215 // TODO(meredithl) : add UMA metrics here.
216 CheckPermissionsBlacklistResult(web_contents, id, requesting_origin,
217 embedding_origin, user_gesture, callback,
218 false);
219 }
220 }
221
222 void PermissionContextBase::CheckPermissionsBlacklistResult(
223 content::WebContents* web_contents,
224 const PermissionRequestID& id,
225 const GURL& requesting_origin,
226 const GURL& embedding_origin,
227 bool user_gesture,
228 const BrowserPermissionCallback& callback,
229 bool permission_blocked) {
230 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
231 if (permission_blocked) {
232 // TODO(meredithl) : add UMA metrics here.
233 web_contents->GetMainFrame()->AddMessageToConsole(
234 content::CONSOLE_MESSAGE_LEVEL_LOG,
235 base::StringPrintf(
236 "%s permission has been auto-blocked.",
237 PermissionUtil::GetPermissionString(permission_type_).c_str()));
238 // Permission has been blacklisted, block the request.
239 // TODO(meredithl) : consider setting the content setting and persisting
240 // the decision to block.
241 callback.Run(CONTENT_SETTING_BLOCK);
242 return;
243 }
244
245 // Site is not blacklisted by Safe Browsing for the requested permission.
104 ContentSetting content_setting = 246 ContentSetting content_setting =
105 GetPermissionStatus(requesting_origin, embedding_origin); 247 GetPermissionStatus(requesting_origin, embedding_origin);
106 if (content_setting == CONTENT_SETTING_ALLOW) { 248 if (content_setting == CONTENT_SETTING_ALLOW) {
107 HostContentSettingsMapFactory::GetForProfile(profile_)->UpdateLastUsage( 249 HostContentSettingsMapFactory::GetForProfile(profile_)->UpdateLastUsage(
108 requesting_origin, embedding_origin, content_settings_type_); 250 requesting_origin, embedding_origin, content_settings_type_);
109 } 251 }
252
110 if (content_setting == CONTENT_SETTING_ALLOW || 253 if (content_setting == CONTENT_SETTING_ALLOW ||
111 content_setting == CONTENT_SETTING_BLOCK) { 254 content_setting == CONTENT_SETTING_BLOCK) {
112 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, 255 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
113 false /* persist */, content_setting); 256 false /* persist */, content_setting);
114 return; 257 return;
115 } 258 }
116 259
117 PermissionUmaUtil::PermissionRequested(permission_type_, requesting_origin, 260 PermissionUmaUtil::PermissionRequested(permission_type_, requesting_origin,
118 embedding_origin, profile_); 261 embedding_origin, profile_);
119 262
120 DecidePermission(web_contents, id, requesting_origin, embedding_origin, 263 DecidePermission(web_contents, id, requesting_origin, embedding_origin,
121 user_gesture, callback); 264 user_gesture, callback);
122 } 265 }
123 266
124 ContentSetting PermissionContextBase::GetPermissionStatus( 267 ContentSetting PermissionContextBase::GetPermissionStatus(
125 const GURL& requesting_origin, 268 const GURL& requesting_origin,
126 const GURL& embedding_origin) const { 269 const GURL& embedding_origin) const {
127
128 // If the permission has been disabled through Finch, block all requests. 270 // If the permission has been disabled through Finch, block all requests.
129 if (IsPermissionKillSwitchOn()) 271 if (IsPermissionKillSwitchOn())
130 return CONTENT_SETTING_BLOCK; 272 return CONTENT_SETTING_BLOCK;
131 273
132 if (IsRestrictedToSecureOrigins() && 274 if (IsRestrictedToSecureOrigins() &&
133 !content::IsOriginSecure(requesting_origin)) { 275 !content::IsOriginSecure(requesting_origin)) {
134 return CONTENT_SETTING_BLOCK; 276 return CONTENT_SETTING_BLOCK;
135 } 277 }
136 278
137 return HostContentSettingsMapFactory::GetForProfile(profile_) 279 return HostContentSettingsMapFactory::GetForProfile(profile_)
138 ->GetContentSetting(requesting_origin, embedding_origin, 280 ->GetContentSetting(requesting_origin, embedding_origin,
139 content_settings_type_, std::string()); 281 content_settings_type_, std::string());
140 } 282 }
141 283
142 void PermissionContextBase::ResetPermission( 284 void PermissionContextBase::ResetPermission(const GURL& requesting_origin,
143 const GURL& requesting_origin, 285 const GURL& embedding_origin) {
144 const GURL& embedding_origin) {
145 HostContentSettingsMapFactory::GetForProfile(profile_) 286 HostContentSettingsMapFactory::GetForProfile(profile_)
146 ->SetContentSettingDefaultScope(requesting_origin, embedding_origin, 287 ->SetContentSettingDefaultScope(requesting_origin, embedding_origin,
147 content_settings_type_, std::string(), 288 content_settings_type_, std::string(),
148 CONTENT_SETTING_DEFAULT); 289 CONTENT_SETTING_DEFAULT);
149 } 290 }
150 291
151 void PermissionContextBase::CancelPermissionRequest( 292 void PermissionContextBase::CancelPermissionRequest(
152 content::WebContents* web_contents, 293 content::WebContents* web_contents,
153 const PermissionRequestID& id) { 294 const PermissionRequestID& id) {
154 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 295 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
(...skipping 19 matching lines...) Expand all
174 const PermissionRequestID& id, 315 const PermissionRequestID& id,
175 const GURL& requesting_origin, 316 const GURL& requesting_origin,
176 const GURL& embedding_origin, 317 const GURL& embedding_origin,
177 bool user_gesture, 318 bool user_gesture,
178 const BrowserPermissionCallback& callback) { 319 const BrowserPermissionCallback& callback) {
179 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 320 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
180 321
181 if (PermissionRequestManager::IsEnabled()) { 322 if (PermissionRequestManager::IsEnabled()) {
182 PermissionRequestManager* permission_request_manager = 323 PermissionRequestManager* permission_request_manager =
183 PermissionRequestManager::FromWebContents(web_contents); 324 PermissionRequestManager::FromWebContents(web_contents);
184 // TODO(felt): sometimes |permission_request_manager| is null. This check is 325 // TODO(felt): sometimes |permission_request_manager| is null. This check
326 // is
dominickn 2016/12/15 03:52:45 Nit: fix formatting here.
meredithl 2016/12/15 04:15:34 Done.
185 // meant to prevent crashes. See crbug.com/457091. 327 // meant to prevent crashes. See crbug.com/457091.
186 if (!permission_request_manager) 328 if (!permission_request_manager)
187 return; 329 return;
188 330
189 std::unique_ptr<PermissionRequest> request_ptr = 331 std::unique_ptr<PermissionRequest> request_ptr =
190 base::MakeUnique<PermissionRequestImpl>( 332 base::MakeUnique<PermissionRequestImpl>(
191 requesting_origin, permission_type_, profile_, user_gesture, 333 requesting_origin, permission_type_, profile_, user_gesture,
192 base::Bind(&PermissionContextBase::PermissionDecided, 334 base::Bind(&PermissionContextBase::PermissionDecided,
193 weak_factory_.GetWeakPtr(), id, requesting_origin, 335 weak_factory_.GetWeakPtr(), id, requesting_origin,
194 embedding_origin, user_gesture, callback), 336 embedding_origin, user_gesture, callback),
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 content_setting); 453 content_setting);
312 } 454 }
313 455
314 bool PermissionContextBase::IsPermissionKillSwitchOn() const { 456 bool PermissionContextBase::IsPermissionKillSwitchOn() const {
315 const std::string param = variations::GetVariationParamValue( 457 const std::string param = variations::GetVariationParamValue(
316 kPermissionsKillSwitchFieldStudy, 458 kPermissionsKillSwitchFieldStudy,
317 PermissionUtil::GetPermissionString(permission_type_)); 459 PermissionUtil::GetPermissionString(permission_type_));
318 460
319 return param == kPermissionsKillSwitchBlockedValue; 461 return param == kPermissionsKillSwitchBlockedValue;
320 } 462 }
463
464 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
465 PermissionContextBase::GetSafeBrowsingDatabaseManager() {
466 safe_browsing::SafeBrowsingService* sb_service =
467 g_browser_process->safe_browsing_service();
468 return sb_service ? sb_service->database_manager() : nullptr;
469 }
OLDNEW
« no previous file with comments | « chrome/browser/permissions/permission_context_base.h ('k') | chrome/browser/permissions/permission_context_base_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698