Medium chrome Memory Corruption 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactMemory corruption in WebAppInstalls
DescriptionMemory corruption in WebAppInstalls
ComponentWebAppInstalls
Sub-componentUI>Browser>WebAppInstalls
Bug ClassMemory Corruption
Tracker518108422
Fix commiteccd6ead9085 (chromium/src) +66/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-10-20

Changed Functions

FunctionChangeNotes
if
chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateReportAbuseDialog.java
modified

Files Changed

  • chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateReportAbuseDialog.java
  • chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialog.java
  • chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialogTest.java
From eccd6ead90856b24c15718976c1dc167ec148b52 Mon Sep 17 00:00:00 2001
From: Yaron Friedman <[email protected]>
Date: Tue, 15 Sep 2026 07:11:58 -0700
Subject: [PATCH] Enable touch filtering and tap protection in WebAPK update dialogs

Configure touch filtering and an initial button tap protection delay when
constructing the modal dialog models for the WebAPK icon and name update
prompt and for the uninstall confirmation prompt it can lead to.

This ensures obscured touch events are filtered out and prevents
unintentional immediate button activations when the dialogs are presented
to the user.

The original patch for WebApkIconNameUpdateDialog was generated by
CodeMender. This CL differs from that patch by logically carrying the fix
forward to the destructive action. WebApkUpdateReportAbuseDialog is reached
from the update prompt's negative button, and its positive button leads to
app uninstallation. Protecting only the first prompt would leave the
tapjacking target that actually destroys user state unguarded, so the
uninstall confirmation is given the same treatment, with matching test
coverage.

This mirrors the protection already applied to comparable prompts, including
AddToHomescreenDialogView and ExtensionInstallDialogBridge.

Bug: 518108422
Co-Authored-By: Yoshisato Yanagisawa <[email protected]>
Change-Id: Icd12dcdb71b3daa41f1feffa2ed269989a1bc61b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8394200
Reviewed-by: Glenn Hartmann <[email protected]>
Commit-Queue: Yaron Friedman <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1698059}
---
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialog.java
index 604c6aa..1634b57 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialog.java
@@ -16,6 +16,7 @@
 import org.chromium.build.annotations.Nullable;
 import org.chromium.chrome.R;
 import org.chromium.ui.LayoutInflaterUtils;
+import org.chromium.ui.UiUtils;
 import org.chromium.ui.modaldialog.DialogDismissalCause;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
@@ -155,6 +156,10 @@
                                 resources,
                                 R.string.webapp_update_negative_button)
                         .with(ModalDialogProperties.TITLE_SCROLLABLE, true)
+                        .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true)
+                        .with(
+                                ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS,
+                                UiUtils.PROMPT_INPUT_PROTECTION_SHORT_DELAY_MS)
                         .build();
 
         mModalDialogManager = manager;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateReportAbuseDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateReportAbuseDialog.java
index e79a6b0..31644764 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateReportAbuseDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateReportAbuseDialog.java
@@ -19,6 +19,7 @@
 import org.chromium.build.annotations.Nullable;
 import org.chromium.chrome.R;
 import org.chromium.ui.LayoutInflaterUtils;
+import org.chromium.ui.UiUtils;
 import org.chromium.ui.modaldialog.DialogDismissalCause;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
@@ -95,7 +96,11 @@
                         .with(
                                 ModalDialogProperties.NEGATIVE_BUTTON_TEXT,
                                 resources,
-                                R.string.webapk_report_abuse_cancel);
+                                R.string.webapk_report_abuse_cancel)
+                        .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true)
+                        .with(
+                                ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS,
+                                UiUtils.PROMPT_INPUT_PROTECTION_SHORT_DELAY_MS);
         if (mShowAbuseCheckbox) {
             View dialogCustomView =
                     LayoutInflaterUtils.inflate(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialogTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialogTest.java
index 36b625a8..df6cf47 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialogTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialogTest.java
@@ -27,6 +27,7 @@
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
+import org.chromium.ui.UiUtils;
 import org.chromium.ui.modaldialog.DialogDismissalCause;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
@@ -219,6 +220,13 @@
                         : null,
                 getUpdateDialogBitmap(R.id.app_icon_new));
 
+        PropertyModel dialogModel = mDialogManager.getCurrentDialogModel();
+        Assert.assertNotNull(dialogModel);
+        Assert.assertTrue(dialogModel.get(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY));
+        Assert.assertEquals(
+                UiUtils.PROMPT_INPUT_PROTECTION_SHORT_DELAY_MS,
+                (long) dialogModel.get(ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS));
+
         mDialogManager.dismissCurrentDialog(
                 clickAccept
                         ? DialogDismissalCause.POSITIVE_BUTTON_CLICKED
@@ -258,6 +266,13 @@
 
         Assert.assertEquals(expectedTitle, getDialogTitle());
 
+        PropertyModel abuseDialogModel = mDialogManager.getCurrentDialogModel();
+        Assert.assertNotNull(abuseDialogModel);
+        Assert.assertTrue(abuseDialogModel.get(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY));
+        Assert.assertEquals(
+                UiUtils.PROMPT_INPUT_PROTECTION_SHORT_DELAY_MS,
+                (long) abuseDialogModel.get(ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS));
+
         mDialogManager.dismissCurrentDialog(
                 clickAccept
                         ? DialogDismissalCause.POSITIVE_BUTTON_CLICKED
@@ -375,4 +390,44 @@
         // Make sure Canceling the dialog does the right thing.
         verifyReportAbuseValues(/* clickAccept= */ false, "short", "Uninstall 'short'?");
     }
+
+    @Test
+    @SmallTest
+    @Feature({"Webapps"})
+    public void testDialogInputProtection() {
+        DialogParams dialogParams = DialogParams.createDefault();
+        dialogParams.iconChanged = true;
+        dialogParams.bitmapBefore = generateTestBitmap(Color.BLUE);
+        dialogParams.bitmapAfter = generateTestBitmap(Color.RED);
+
+        WebApkIconNameUpdateDialog dialog = new WebApkIconNameUpdateDialog();
+        Context context =
+                new ContextThemeWrapper(
+                        ApplicationProvider.getApplicationContext(),
+                        R.style.Theme_BrowserUI_DayNight);
+
+        dialog.show(
+                context,
+                mDialogManager,
+                /* packageName= */ "",
+                dialogParams.iconChanged,
+                dialogParams.shortNameChanged,
+                dialogParams.nameChanged,
+                dialogParams.shortNameBefore,
+                dialogParams.shortNameAfter,
+                dialogParams.nameBefore,
+                dialogParams.nameAfter,
+                dialogParams.bitmapBefore,
+                dialogParams.bitmapAfter,
+                false,
+                false,
+                this::onUpdateDialogResult);
+
+        PropertyModel model = mDialogManager.getCurrentDialogModel();
+        Assert.assertNotNull(model);
+        Assert.assertTrue(model.get(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY));
+        Assert.assertEquals(
+                UiUtils.PROMPT_INPUT_PROTECTION_SHORT_DELAY_MS,
+                (long) model.get(ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS));
+    }
 }
Loading diff…

Original Bug Report

reported by [email protected]

Tapjacking and clickjacking protection missing in WebApkIconNameUpdateDialog

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: The WebApkIconNameUpdateDialog, which serves as a security consent gate when an installed WebAPK updates its name or icon, lacks crucial input-protection properties. This omission leaves the dialog vulnerable to overlay/tapjacking and double-tap input-timing attacks. As a result, a malicious site could potentially bypass user consent to silently spoof an application’s launcher identity on the home screen.

Affected files:

  • chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialog.java
  • chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java

Estimated timestamp from git blame: 2021-05-19

Description

When an installed WebAPK (Progressive Web App on Android) changes its launcher name or icon, Chrome displays WebApkIconNameUpdateDialog to request explicit user consent. This prevents a WebAPK from silently masquerading as a high-value application (such as a banking app or system tool) on the device launcher.

However, the PropertyModel for WebApkIconNameUpdateDialog is constructed without the following critical input-protection keys:

  • ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY (enables touch filtering to block overlay/tapjacking attacks).
  • ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS (enables a temporary tap-delay window to prevent accidental clicks or double-taps).

Because these properties are missing, ModalDialogView defaults both defenses to off (mFilterTouchForSecurity = false and mButtonTapProtectionDurationMs = 0). Consequently, the positive confirmation button is immediately clickable upon dialog presentation and is vulnerable to touch events delivered through obscured/overlay windows.

Potential Impact and Exploitation Scenarios

An attacker who controls an installed WebAPK can potentially orchestrate a silent, persistent launcher-level identity spoof using two attack variants:

  1. Variant A: Input-Timing/Double-Tap Attack The attacker’s webpage prompts the user to rapidly tap or spam click on a specific location (e.g., in a simple clicker game). The attacker coordinates a WebAPK update check so that the consent dialog appears immediately prior to a tap in the sequence. Without the protection period, the in-flight tap is instantly processed on the dialog’s “OK” button, automatically approving the identity modification.

  2. Variant B: Overlay/Tapjacking Attack A co-installed malicious application with overlay (SYSTEM_ALERT_WINDOW) permissions draws a deceptive UI directly over the dialog’s action button. Because touch filtering for security is omitted on the dialog, obscured touches are successfully dispatched to Chrome’s underlying dialog button.

Note: These are potential/suggested exploitation steps, as our automated analysis tools do not have the ability to run functional exploit code to confirm.

Affected Code

  • File: chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIconNameUpdateDialog.java
    • Lines 143-158 in show(...) (where PropertyModel is built without the security properties).
  • File: chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java

Suggested Fix

Ensure that both ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY and ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS are explicitly added to the PropertyModel builder in WebApkIconNameUpdateDialog.java, consistent with other security-sensitive dialogs (such as ExtensionInstallDialogBridge):

mDialogModel =
        new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
                .with(ModalDialogProperties.CONTROLLER, this)
                .with(ModalDialogProperties.TITLE, resources, titleId)
                .with(ModalDialogProperties.MESSAGE_PARAGRAPH_1, explanation)
                .with(ModalDialogProperties.CUSTOM_VIEW, dialogCustomView)
                .with(
                        ModalDialogProperties.BUTTON_STYLES,
                        ModalDialogProperties.ButtonStyles.PRIMARY_FILLED_NEGATIVE_OUTLINE)
                .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, R.string.ok)
                .with(
                        ModalDialogProperties.NEGATIVE_BUTTON_TEXT,
                        resources,
                        R.string.webapp_update_negative_button)
                .with(ModalDialogProperties.TITLE_SCROLLABLE, true)
                .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true)
                .with(
                        ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS,
                        ModalDialogView.LONG_TAP_PROTECTION_DURATION_MS)
                .build();

Evaluated with Chrome root at commit: fb72408a8493c46bc75fae1c70d03daec96b3040


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker