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

Side by Side Diff: chrome/browser/extensions/active_script_controller.cc

Issue 313453002: Resubmit: Block content scripts from executing until user grants permission (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tests Created 6 years, 6 months 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 | Annotate | Revision Log
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/extensions/active_script_controller.h" 5 #include "chrome/browser/extensions/active_script_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 29 matching lines...) Expand all
40 : closure(closure), 40 : closure(closure),
41 page_id(page_id) { 41 page_id(page_id) {
42 } 42 }
43 43
44 ActiveScriptController::PendingRequest::~PendingRequest() { 44 ActiveScriptController::PendingRequest::~PendingRequest() {
45 } 45 }
46 46
47 ActiveScriptController::ActiveScriptController( 47 ActiveScriptController::ActiveScriptController(
48 content::WebContents* web_contents) 48 content::WebContents* web_contents)
49 : content::WebContentsObserver(web_contents), 49 : content::WebContentsObserver(web_contents),
50 enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()) { 50 enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()),
51 extension_registry_observer_(this) {
51 CHECK(web_contents); 52 CHECK(web_contents);
53 extension_registry_observer_.Add(
54 ExtensionRegistry::Get(web_contents->GetBrowserContext()));
52 } 55 }
53 56
54 ActiveScriptController::~ActiveScriptController() { 57 ActiveScriptController::~ActiveScriptController() {
55 LogUMA(); 58 LogUMA();
56 } 59 }
57 60
58 // static 61 // static
59 ActiveScriptController* ActiveScriptController::GetForWebContents( 62 ActiveScriptController* ActiveScriptController::GetForWebContents(
60 content::WebContents* web_contents) { 63 content::WebContents* web_contents) {
61 if (!web_contents) 64 if (!web_contents)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 if (list.size() == 1u) 106 if (list.size() == 1u)
104 LocationBarController::NotifyChange(web_contents()); 107 LocationBarController::NotifyChange(web_contents());
105 } 108 }
106 109
107 void ActiveScriptController::OnActiveTabPermissionGranted( 110 void ActiveScriptController::OnActiveTabPermissionGranted(
108 const Extension* extension) { 111 const Extension* extension) {
109 RunPendingForExtension(extension); 112 RunPendingForExtension(extension);
110 } 113 }
111 114
112 void ActiveScriptController::OnAdInjectionDetected( 115 void ActiveScriptController::OnAdInjectionDetected(
113 const std::set<std::string> ad_injectors) { 116 const std::set<std::string>& ad_injectors) {
114 // We're only interested in data if there are ad injectors detected. 117 // We're only interested in data if there are ad injectors detected.
115 if (ad_injectors.empty()) 118 if (ad_injectors.empty())
116 return; 119 return;
117 120
118 size_t num_preventable_ad_injectors = 121 size_t num_preventable_ad_injectors =
119 base::STLSetIntersection<std::set<std::string> >( 122 base::STLSetIntersection<std::set<std::string> >(
120 ad_injectors, permitted_extensions_).size(); 123 ad_injectors, permitted_extensions_).size();
121 124
122 UMA_HISTOGRAM_COUNTS_100( 125 UMA_HISTOGRAM_COUNTS_100(
123 "Extensions.ActiveScriptController.PreventableAdInjectors", 126 "Extensions.ActiveScriptController.PreventableAdInjectors",
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 ++request) { 209 ++request) {
207 // Only run if it's on the proper page. 210 // Only run if it's on the proper page.
208 if (request->page_id == page_id) 211 if (request->page_id == page_id)
209 request->closure.Run(); 212 request->closure.Run();
210 } 213 }
211 214
212 // Inform the location bar that the action is now gone. 215 // Inform the location bar that the action is now gone.
213 LocationBarController::NotifyChange(web_contents()); 216 LocationBarController::NotifyChange(web_contents());
214 } 217 }
215 218
216 void ActiveScriptController::OnNotifyExtensionScriptExecution( 219 void ActiveScriptController::OnRequestContentScriptPermission(
217 const std::string& extension_id, 220 const std::string& extension_id,
218 int page_id) { 221 int page_id,
222 int request_id) {
219 if (!Extension::IdIsValid(extension_id)) { 223 if (!Extension::IdIsValid(extension_id)) {
220 NOTREACHED() << "'" << extension_id << "' is not a valid id."; 224 NOTREACHED() << "'" << extension_id << "' is not a valid id.";
221 return; 225 return;
222 } 226 }
223 227
224 const Extension* extension = 228 const Extension* extension =
225 ExtensionRegistry::Get(web_contents()->GetBrowserContext()) 229 ExtensionRegistry::Get(web_contents()->GetBrowserContext())
226 ->enabled_extensions().GetByID(extension_id); 230 ->enabled_extensions().GetByID(extension_id);
227 // We shouldn't allow extensions which are no longer enabled to run any 231 // We shouldn't allow extensions which are no longer enabled to run any
228 // scripts. Ignore the request. 232 // scripts. Ignore the request.
229 if (!extension) 233 if (!extension)
230 return; 234 return;
231 235
232 // Right now, we allow all content scripts to execute, but notify the 236 // If the request id is -1, that signals that the content script has already
233 // controller of them. 237 // ran (because this feature is not enabled). Add the extension to the list of
234 // TODO(rdevlin.cronin): Fix this in a future CL. 238 // permitted extensions (for metrics), and return immediately.
235 if (RequiresUserConsentForScriptInjection(extension)) 239 if (request_id == -1) {
236 RequestScriptInjection(extension, page_id, base::Bind(&base::DoNothing)); 240 DCHECK(!enabled_);
241 permitted_extensions_.insert(extension->id());
242 return;
243 }
244
245 if (RequiresUserConsentForScriptInjection(extension)) {
246 // This base::Unretained() is safe, because the callback is only invoked by
247 // this object.
248 RequestScriptInjection(
249 extension,
250 page_id,
251 base::Bind(&ActiveScriptController::GrantContentScriptPermission,
252 base::Unretained(this),
253 request_id));
254 } else {
255 GrantContentScriptPermission(request_id);
256 }
257 }
258
259 void ActiveScriptController::GrantContentScriptPermission(int request_id) {
260 content::RenderViewHost* render_view_host =
261 web_contents()->GetRenderViewHost();
262 if (render_view_host) {
263 render_view_host->Send(new ExtensionMsg_GrantContentScriptPermission(
264 render_view_host->GetRoutingID(),
265 request_id));
266 }
237 } 267 }
238 268
239 bool ActiveScriptController::OnMessageReceived(const IPC::Message& message) { 269 bool ActiveScriptController::OnMessageReceived(const IPC::Message& message) {
240 bool handled = true; 270 bool handled = true;
241 IPC_BEGIN_MESSAGE_MAP(ActiveScriptController, message) 271 IPC_BEGIN_MESSAGE_MAP(ActiveScriptController, message)
242 IPC_MESSAGE_HANDLER(ExtensionHostMsg_NotifyExtensionScriptExecution, 272 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestContentScriptPermission,
243 OnNotifyExtensionScriptExecution) 273 OnRequestContentScriptPermission)
244 IPC_MESSAGE_UNHANDLED(handled = false) 274 IPC_MESSAGE_UNHANDLED(handled = false)
245 IPC_END_MESSAGE_MAP() 275 IPC_END_MESSAGE_MAP()
246 return handled; 276 return handled;
247 } 277 }
248 278
279 void ActiveScriptController::OnExtensionUnloaded(
280 content::BrowserContext* browser_context,
281 const Extension* extension,
282 UnloadedExtensionInfo::Reason reason) {
283 PendingRequestMap::iterator iter = pending_requests_.find(extension->id());
284 if (iter != pending_requests_.end()) {
285 pending_requests_.erase(iter);
not at google - send to devlin 2014/06/02 21:28:17 seems like you could delete the entry from pending
Devlin 2014/06/02 23:07:52 Done.
286 LocationBarController::NotifyChange(web_contents());
287 }
288 }
289
249 void ActiveScriptController::LogUMA() const { 290 void ActiveScriptController::LogUMA() const {
250 UMA_HISTOGRAM_COUNTS_100( 291 UMA_HISTOGRAM_COUNTS_100(
251 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", 292 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage",
252 pending_requests_.size()); 293 pending_requests_.size());
253 294
254 // We only log the permitted extensions metric if the feature is enabled, 295 // We only log the permitted extensions metric if the feature is enabled,
255 // because otherwise the data will be boring (100% allowed). 296 // because otherwise the data will be boring (100% allowed).
256 if (enabled_) { 297 if (enabled_) {
257 UMA_HISTOGRAM_COUNTS_100( 298 UMA_HISTOGRAM_COUNTS_100(
258 "Extensions.ActiveScriptController.PermittedExtensions", 299 "Extensions.ActiveScriptController.PermittedExtensions",
259 permitted_extensions_.size()); 300 permitted_extensions_.size());
260 UMA_HISTOGRAM_COUNTS_100( 301 UMA_HISTOGRAM_COUNTS_100(
261 "Extensions.ActiveScriptController.DeniedExtensions", 302 "Extensions.ActiveScriptController.DeniedExtensions",
262 pending_requests_.size()); 303 pending_requests_.size());
263 } 304 }
264 } 305 }
265 306
266 } // namespace extensions 307 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698