Chrome · CustomTabs
CVE-2026-87597
Logic Error in CustomTabs
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java |
modified |
Files Changed
chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.javachrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java
Patch
From 3bd23769cab8ef0cc0512054a26c467eeeda2c53 Mon Sep 17 00:00:00 2001
From: Peter E Conn <peconn@google.com>
Date: Mon, 13 Jul 2026 08:43:17 -0700
Subject: [PATCH] Fix TWA SecurityLevel checks for toolbar hiding
Instead of specifically checking for ConnectionSecurityLevel.DANGEROUS
to force-show the browser controls, check if the security level is
SECURE. This ensures that the URL bar is shown not only for DANGEROUS
but also for WARNING and NONE states (e.g. mixed content, http).
This prevents origins from suppressing security indicators with TWAs.
TAG=agy
CONV=c4062454-4b45-484e-9930-7d4b9c0288d5
Fix: 533018632
Change-Id: Ic5c84ccc6650b7c346898e0603112761473aefb3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8065230
Reviewed-by: Daniel Murphy <dmurph@chromium.org>
Commit-Queue: Peter Conn <peconn@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1661143}
---
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java
index 4755dab..9701c6a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java
@@ -115,10 +115,13 @@
}
private @BrowserControlsState int computeBrowserControlsState(@Nullable Tab tab) {
- // Force browser controls to show when the security level is dangerous for consistency with
- // TabStateBrowserControlsVisibilityDelegate.
- if (tab != null && getSecurityLevel(tab) == ConnectionSecurityLevel.DANGEROUS) {
- return BrowserControlsState.SHOWN;
+ // Force browser controls to show when the security level is dangerous or warning.
+ if (tab != null) {
+ int securityLevel = getSecurityLevel(tab);
+ if (securityLevel == ConnectionSecurityLevel.DANGEROUS
+ || securityLevel == ConnectionSecurityLevel.WARNING) {
+ return BrowserControlsState.SHOWN;
+ }
}
return shouldShowBrowserControlsAndCloseButton(tab)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java
index 5b70936..e560e63 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManagerTest.java
@@ -100,6 +100,25 @@
assertFalse(getLastCloseButtonVisibility());
}
+ /** Browser controls should be shown for pages with mixed content warnings. */
+ @Test
+ public void testWarningSecurityLevel() {
+ mController = buildController(mock(BrowserServicesIntentDataProvider.class));
+ setTabSecurityLevel(ConnectionSecurityLevel.WARNING);
+ mController.updateIsInAppMode(true);
+ assertEquals(BrowserControlsState.SHOWN, getLastBrowserControlsState());
+ assertFalse(getLastCloseButtonVisibility());
+ }
+
+ /** Browser controls should be hidden for HTTP connections and mixed forms. */
+ @Test
+ public void testNoneSecurityLevel() {
+ mController = buildController(mock(BrowserServicesIntentDataProvider.class));
+ setTabSecurityLevel(ConnectionSecurityLevel.NONE);
+ mController.updateIsInAppMode(true);
+ assertEquals(BrowserControlsState.HIDDEN, getLastBrowserControlsState());
+ }
+
/** Browser controls should not be shown for WebAPKs with 'minimal-ui' display mode. */
@Test
public void testMinimalUiDisplayMode() {
@@ -201,13 +220,16 @@
private TrustedWebActivityBrowserControlsVisibilityManager buildController(
BrowserServicesIntentDataProvider intentDataProvider) {
- return spy(
- new TrustedWebActivityBrowserControlsVisibilityManager(
- mTabObserverRegistrar,
- mTabProvider,
- mToolbarCoordinator,
- mCloseButtonVisibilityManager,
- intentDataProvider));
+ TrustedWebActivityBrowserControlsVisibilityManager controller =
+ spy(
+ new TrustedWebActivityBrowserControlsVisibilityManager(
+ mTabObserverRegistrar,
+ mTabProvider,
+ mToolbarCoordinator,
+ mCloseButtonVisibilityManager,
+ intentDataProvider));
+ doReturn(ConnectionSecurityLevel.SECURE).when(controller).getSecurityLevel(any());
+ return controller;
}
/** Returns the current browser controls state. */
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.
References
On This Page