Commit 6f9f33b6 authored by Mustaq Ahmed's avatar Mustaq Ahmed Committed by Commit Bot

Extension: remove USER_GESTURE_ENABLED state from tab-change events.

A past fix for activation propagation from an extension button to
extension script seems to have added additional user activation
propagation path from tab-strip to all installed extensions:
https://chromiumcodereview.appspot.com/10821120/

This crack caused every tab-switching to activate /all/ installed
extensions, which seems bad.  Because of this, we encountered a security
issue with unintended top frame navigation from an iframe.  (Luckily
only tab switching was affected, not tab clicking.)

A user interaction with the tab-strip is different from an interaction
with extension buttons.  Tab-strip interactions are similar to those
on any browser-provided UI element like top menu: they don't at all
indicate the user's intention to interact with any extension or website.
Therefore, like clicks on top-menu and unlike clicks on extension
buttons, tab-switching should suppress activating any background script
thus prevent access to use user-activation gated APIs like popup,
fullscreen, navigation, etc.

Bug: 957633, 1035315
Change-Id: I8d56e02a3a2966521b7bbc4f4efadf67e1acc371
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2072654Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744802}
parent f01cecd1
...@@ -233,7 +233,7 @@ void TabsEventRouter::OnTabStripModelChanged( ...@@ -233,7 +233,7 @@ void TabsEventRouter::OnTabStripModelChanged(
if (selection.active_tab_changed()) { if (selection.active_tab_changed()) {
DispatchActiveTabChanged(selection.old_contents, selection.new_contents, DispatchActiveTabChanged(selection.old_contents, selection.new_contents,
selection.new_model.active(), selection.reason); selection.new_model.active());
} }
if (selection.selection_changed()) { if (selection.selection_changed()) {
...@@ -398,8 +398,7 @@ void TabsEventRouter::DispatchTabDetachedAt(WebContents* contents, ...@@ -398,8 +398,7 @@ void TabsEventRouter::DispatchTabDetachedAt(WebContents* contents,
void TabsEventRouter::DispatchActiveTabChanged(WebContents* old_contents, void TabsEventRouter::DispatchActiveTabChanged(WebContents* old_contents,
WebContents* new_contents, WebContents* new_contents,
int index, int index) {
int reason) {
auto args = std::make_unique<base::ListValue>(); auto args = std::make_unique<base::ListValue>();
int tab_id = ExtensionTabUtil::GetTabId(new_contents); int tab_id = ExtensionTabUtil::GetTabId(new_contents);
args->AppendInteger(tab_id); args->AppendInteger(tab_id);
...@@ -414,24 +413,21 @@ void TabsEventRouter::DispatchActiveTabChanged(WebContents* old_contents, ...@@ -414,24 +413,21 @@ void TabsEventRouter::DispatchActiveTabChanged(WebContents* old_contents,
// deprecated events take two arguments: tabId, {windowId}. // deprecated events take two arguments: tabId, {windowId}.
Profile* profile = Profile* profile =
Profile::FromBrowserContext(new_contents->GetBrowserContext()); Profile::FromBrowserContext(new_contents->GetBrowserContext());
EventRouter::UserGestureState gesture =
reason & CHANGE_REASON_USER_GESTURE
? EventRouter::USER_GESTURE_ENABLED
: EventRouter::USER_GESTURE_NOT_ENABLED;
DispatchEvent(profile, events::TABS_ON_SELECTION_CHANGED, DispatchEvent(profile, events::TABS_ON_SELECTION_CHANGED,
api::tabs::OnSelectionChanged::kEventName, api::tabs::OnSelectionChanged::kEventName,
args->CreateDeepCopy(), gesture); args->CreateDeepCopy(), EventRouter::USER_GESTURE_UNKNOWN);
DispatchEvent(profile, events::TABS_ON_ACTIVE_CHANGED, DispatchEvent(profile, events::TABS_ON_ACTIVE_CHANGED,
api::tabs::OnActiveChanged::kEventName, std::move(args), api::tabs::OnActiveChanged::kEventName, std::move(args),
gesture); EventRouter::USER_GESTURE_UNKNOWN);
// The onActivated event takes one argument: {windowId, tabId}. // The onActivated event takes one argument: {windowId, tabId}.
auto on_activated_args = std::make_unique<base::ListValue>(); auto on_activated_args = std::make_unique<base::ListValue>();
object_args->Set(tabs_constants::kTabIdKey, std::make_unique<Value>(tab_id)); object_args->Set(tabs_constants::kTabIdKey, std::make_unique<Value>(tab_id));
on_activated_args->Append(std::move(object_args)); on_activated_args->Append(std::move(object_args));
DispatchEvent(profile, events::TABS_ON_ACTIVATED, DispatchEvent(
api::tabs::OnActivated::kEventName, profile, events::TABS_ON_ACTIVATED, api::tabs::OnActivated::kEventName,
std::move(on_activated_args), gesture); std::move(on_activated_args), EventRouter::USER_GESTURE_UNKNOWN);
} }
void TabsEventRouter::DispatchTabSelectionChanged( void TabsEventRouter::DispatchTabSelectionChanged(
......
...@@ -95,8 +95,7 @@ class TabsEventRouter : public TabStripModelObserver, ...@@ -95,8 +95,7 @@ class TabsEventRouter : public TabStripModelObserver,
bool was_active); bool was_active);
void DispatchActiveTabChanged(content::WebContents* old_contents, void DispatchActiveTabChanged(content::WebContents* old_contents,
content::WebContents* new_contents, content::WebContents* new_contents,
int index, int index);
int reason);
void DispatchTabSelectionChanged(TabStripModel* tab_strip_model, void DispatchTabSelectionChanged(TabStripModel* tab_strip_model,
const ui::ListSelectionModel& old_model); const ui::ListSelectionModel& old_model);
void DispatchTabMoved(content::WebContents* contents, void DispatchTabMoved(content::WebContents* contents,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment