Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactIncorrect security UI in SplitView
DescriptionIncorrect security UI in SplitView
ComponentSplitView
Bug ClassLogic Error
Tracker507099867
Fix commit38cdd6696fa0 (chromium/src) +57/-0
CISA KEVNot listed
CreditedFARISSAL B
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
if
chrome/browser/webshare/BUILD.gn
modified
IN_PROC_BROWSER_TEST_F
chrome/browser/webshare/share_service_browsertest.cc
modified

Files Changed

  • chrome/browser/webshare/BUILD.gn
  • chrome/browser/webshare/chromeos/sharesheet_client.cc
  • chrome/browser/webshare/mac/sharing_service_operation.mm
  • chrome/browser/webshare/share_service_browsertest.cc
  • chrome/browser/webshare/win/share_operation.cc
From 38cdd6696fa03e758da8973657d1e1695a33f410 Mon Sep 17 00:00:00 2001
From: Alison Gale <agale@chromium.org>
Date: Mon, 11 May 2026 08:51:38 -0700
Subject: [PATCH] [SxS] Prevent sharing via WebShare API from inactive WebContents

With Split View, tabs can be visible but inactive. So it is possible for
an inactive tab in a split to trigger a share dialog which currently
renders in a misleading way. This is fixed by just blocking share from
inactive tabs on all platforms.

Bug: 507099867
Change-Id: I08acac6194083eec33a9578971ab5b2c7d425dcd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7828287
Reviewed-by: Dibyajyoti Pal <dibyapal@chromium.org>
Commit-Queue: Alison Gale <agale@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1628602}
---

diff --git a/chrome/browser/webshare/BUILD.gn b/chrome/browser/webshare/BUILD.gn
index 7b03fda..79b56c0 100644
--- a/chrome/browser/webshare/BUILD.gn
+++ b/chrome/browser/webshare/BUILD.gn
@@ -143,6 +143,7 @@
       "//content/test:test_support",
       "//net:test_support",
       "//testing/gtest",
+      "//ui/base",
     ]
 
     if (is_chromeos) {
diff --git a/chrome/browser/webshare/chromeos/sharesheet_client.cc b/chrome/browser/webshare/chromeos/sharesheet_client.cc
index 6f03a4ad..2e35bf6 100644
--- a/chrome/browser/webshare/chromeos/sharesheet_client.cc
+++ b/chrome/browser/webshare/chromeos/sharesheet_client.cc
@@ -30,6 +30,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/services/app_service/public/cpp/intent.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
+#include "components/tabs/public/tab_interface.h"
 #include "components/visibility_timer/visibility_timer_tab_helper.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -146,6 +147,14 @@
     return;
   }
 
+  // If the tab is no longer active, return permission denied.
+  tabs::TabInterface* tab_interface =
+      tabs::TabInterface::MaybeGetFromContents(web_contents());
+  if (tab_interface && !tab_interface->IsActivated()) {
+    std::move(callback).Run(blink::mojom::ShareError::PERMISSION_DENIED);
+    return;
+  }
+
   current_share_ = CurrentShare();
   current_share_->files = std::move(files);
   current_share_->directory =
diff --git a/chrome/browser/webshare/mac/sharing_service_operation.mm b/chrome/browser/webshare/mac/sharing_service_operation.mm
index 9325106e..3e90569d 100644
--- a/chrome/browser/webshare/mac/sharing_service_operation.mm
+++ b/chrome/browser/webshare/mac/sharing_service_operation.mm
@@ -21,6 +21,7 @@
 #include "chrome/browser/webshare/prepare_subdirectory_task.h"
 #include "chrome/browser/webshare/share_service_impl.h"
 #include "chrome/browser/webshare/store_files_task.h"
+#include "components/tabs/public/tab_interface.h"
 #include "components/visibility_timer/visibility_timer_tab_helper.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/render_widget_host_view.h"
@@ -89,6 +90,14 @@
     return;
   }
 
+  // If the tab is no longer active, return permission denied.
+  tabs::TabInterface* tab_interface =
+      tabs::TabInterface::MaybeGetFromContents(web_contents_.get());
+  if (tab_interface && !tab_interface->IsActivated()) {
+    std::move(callback_).Run(blink::mojom::ShareError::PERMISSION_DENIED);
+    return;
+  }
+
   if (shared_files_.size() == 0) {
     GetSharePickerCallback().Run(
         web_contents_.get(), file_paths_, text_, title_, url_,
diff --git a/chrome/browser/webshare/share_service_browsertest.cc b/chrome/browser/webshare/share_service_browsertest.cc
index 1262ff5a..2af6b04 100644
--- a/chrome/browser/webshare/share_service_browsertest.cc
+++ b/chrome/browser/webshare/share_service_browsertest.cc
@@ -7,12 +7,16 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/tabs/split_tab_metrics.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/webshare/share_service_impl.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/safe_browsing/content/common/file_type_policies_test_util.h"
 #include "components/safe_browsing/core/browser/db/fake_database_manager.h"
+#include "components/tabs/public/tab_interface.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/test/browser_test.h"
@@ -101,6 +105,31 @@
                                      WebShareMethod::kShare, kRepeats);
 }
 
+IN_PROC_BROWSER_TEST_F(ShareServiceBrowserTest, InactiveWebContents) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/webshare/index.html")));
+  content::WebContents* contents_0 =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Create a split and verify there are now 2 tabs
+  chrome::NewSplitTab(browser(),
+                      split_tabs::SplitTabCreatedSource::kToolbarButton);
+  ASSERT_EQ(2, browser()->tab_strip_model()->count());
+  EXPECT_TRUE(browser()->tab_strip_model()->GetTabAtIndex(0)->IsSplit());
+  EXPECT_TRUE(browser()->tab_strip_model()->GetTabAtIndex(1)->IsSplit());
+
+  // Tab 0 is now inactive.
+  tabs::TabInterface* tab_0 = tabs::TabInterface::GetFromContents(contents_0);
+  EXPECT_FALSE(tab_0->IsActivated());
+
+  // Initiate share from tab 0. Permission in denied because it's inactive.
+  std::string result =
+      content::EvalJs(contents_0, "share_text('hello')").ExtractString();
+  EXPECT_THAT(result, testing::HasSubstr("share failed"));
+  EXPECT_THAT(result, testing::HasSubstr("NotAllowedError"));
+}
+
 #if BUILDFLAG(IS_WIN)
 IN_PROC_BROWSER_TEST_F(ShareServiceBrowserTest, Fullscreen) {
   base::HistogramTester histogram_tester;
diff --git a/chrome/browser/webshare/win/share_operation.cc b/chrome/browser/webshare/win/share_operation.cc
index 1eeb3cf..6769897 100644
--- a/chrome/browser/webshare/win/share_operation.cc
+++ b/chrome/browser/webshare/win/share_operation.cc
@@ -26,6 +26,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/webshare/share_service_impl.h"
 #include "chrome/browser/webshare/win/show_share_ui_for_window_operation.h"
+#include "components/tabs/public/tab_interface.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
@@ -386,6 +387,14 @@
     return;
   }
 
+  // If the tab is no longer active, return permission denied.
+  tabs::TabInterface* tab_interface =
+      tabs::TabInterface::MaybeGetFromContents(web_contents_.get());
+  if (tab_interface && !tab_interface->IsActivated()) {
+    Complete(blink::mojom::ShareError::PERMISSION_DENIED);
+    return;
+  }
+
   if (files.size() > 0) {
     // Determine the source for use with the OS IAttachmentExecute.
     // If the source cannot be determined, does not appear to be valid,
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/webshare/share_service_browsertest.cc b/chrome/browser/webshare/share_service_browsertest.cc
index 1262ff5a..2af6b04 100644
--- a/chrome/browser/webshare/share_service_browsertest.cc
+++ b/chrome/browser/webshare/share_service_browsertest.cc
@@ -7,12 +7,16 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/tabs/split_tab_metrics.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/webshare/share_service_impl.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/safe_browsing/content/common/file_type_policies_test_util.h"
 #include "components/safe_browsing/core/browser/db/fake_database_manager.h"
+#include "components/tabs/public/tab_interface.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/test/browser_test.h"
@@ -101,6 +105,31 @@
                                      WebShareMethod::kShare, kRepeats);
 }
 
+IN_PROC_BROWSER_TEST_F(ShareServiceBrowserTest, InactiveWebContents) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL("/webshare/index.html")));
+  content::WebContents* contents_0 =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Create a split and verify there are now 2 tabs
+  chrome::NewSplitTab(browser(),
+                      split_tabs::SplitTabCreatedSource::kToolbarButton);
+  ASSERT_EQ(2, browser()->tab_strip_model()->count());
+  EXPECT_TRUE(browser()->tab_strip_model()->GetTabAtIndex(0)->IsSplit());
+  EXPECT_TRUE(browser()->tab_strip_model()->GetTabAtIndex(1)->IsSplit());
+
+  // Tab 0 is now inactive.
+  tabs::TabInterface* tab_0 = tabs::TabInterface::GetFromContents(contents_0);
+  EXPECT_FALSE(tab_0->IsActivated());
+
+  // Initiate share from tab 0. Permission in denied because it's inactive.
+  std::string result =
+      content::EvalJs(contents_0, "share_text('hello')").ExtractString();
+  EXPECT_THAT(result, testing::HasSubstr("share failed"));
+  EXPECT_THAT(result, testing::HasSubstr("NotAllowedError"));
+}
+
 #if BUILDFLAG(IS_WIN)
 IN_PROC_BROWSER_TEST_F(ShareServiceBrowserTest, Fullscreen) {
   base::HistogramTester histogram_tester;
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.