Medium firefox Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionInformation disclosure in the Privacy component in Firefox for Android
ComponentCore
Bug ClassLogic Error
Tracker2021964
Fix commita0dd12d38cbd (firefox) +88/-46
CISA KEVNot listed
CreditedSatoki Tsuji
Disclosed2026-07-21

Changed Functions

FunctionChangeNotes
if
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt
modified
if
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt
modified
if
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/ShareController.kt
modified
if
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt
modified

Files Changed

  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/ShareController.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt
index 32c6d2ebbce..19f8ccbe027 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt
@@ -380,7 +380,13 @@ class BrowserToolbarMiddleware(
 
                 val selectedTab = browserStore.state.selectedTab
                 val url = selectedTab?.readerState?.activeUrl ?: selectedTab?.content?.url
-                clipboard.text = url
+                val isPrivate = selectedTab?.content?.private ?: true
+
+                if (isPrivate) {
+                    clipboard.sensitiveText = url
+                } else {
+                    clipboard.text = url
+                }
 
                 // Android 13+ shows by default a popup for copied text.
                 // Avoid overlapping popups informing the user when the URL is copied to the clipboard.
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt
index a9cded0dd92..9e3c25fcf9b 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/CustomTabBrowserToolbarMiddleware.kt
@@ -279,24 +279,34 @@ class CustomTabBrowserToolbarMiddleware(
                 )
             }
 
-            is CopyToClipboardClicked -> {
-                Events.copyUrlTapped.record(NoExtras())
-
-                clipboard.text = customTab?.content?.url?.also {
-                    // Android 13+ shows by default a popup for copied text.
-                    // Avoid overlapping popups informing the user when the URL is copied to the clipboard.
-                    // and only show our snackbar when Android will not show an indication by default.
-                    // See https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications).
-                    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
-                        appStore.dispatch(URLCopiedToClipboard)
-                    }
-                }
-            }
+            is CopyToClipboardClicked -> handleCopyToClipboard()
 
             else -> next(action)
         }
     }
 
+    private fun handleCopyToClipboard() {
+        Events.copyUrlTapped.record(NoExtras())
+        val currentTab = customTab
+        val url = currentTab?.content?.url
+        // For added safety unless the current tab is explicitly set to non-private,
+        // fall back to sensitiveText even if the check comes back as null.
+        if (currentTab?.content?.private == false) {
+            clipboard.text = url
+        } else {
+            clipboard.sensitiveText = url
+        }
+        url?.also {
+            // Android 13+ shows by default a popup for copied text.
+            // Avoid overlapping popups informing the user when the URL is copied to the clipboard.
+            // and only show our snackbar when Android will not show an indication by default.
+            // See https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications).
+            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
+                appStore.dispatch(URLCopiedToClipboard)
+            }
+        }
+    }
+
     private fun observePageOriginUpdates(store: Store<BrowserToolbarState, BrowserToolbarAction>) {
         browserStore.observeWhileActive {
             mapNotNull { state -> state.findCustomTab(customTabId) }
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/ShareController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/ShareController.kt
index 08537ca9377..f87689e092c 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/ShareController.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/share/ShareController.kt
@@ -6,6 +6,7 @@ package org.mozilla.fenix.share
 
 import android.content.ActivityNotFoundException
 import android.content.ClipData
+import android.content.ClipDescription
 import android.content.ClipboardManager
 import android.content.Context
 import android.content.Intent
@@ -16,6 +17,8 @@ import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
 import android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT
 import android.net.Uri
 import android.os.Build
+import android.os.PersistableBundle
+import androidx.annotation.RequiresApi
 import androidx.annotation.VisibleForTesting
 import androidx.core.net.toUri
 import androidx.navigation.NavController
@@ -126,6 +129,7 @@ class DefaultShareController(
         dismiss(ShareController.Result.DISMISSED)
     }
 
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     override fun handleShareToApp(app: AppShareOption) {
         Events.shareToApp.record(
             getShareToAppSafeExtra(
@@ -296,19 +300,18 @@ class DefaultShareController(
         return "data:,${Uri.encode(this)}"
     }
 
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     private fun copyClipboard() {
         val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
         val clipData = ClipData.newPlainText(getShareSubject(), getShareText())
 
-        clipboardManager.setPrimaryClip(clipData)
-
-        // Android 13+ shows by default a popup for copied text.
-        // Avoid overlapping popups informing the user when the URL is copied to the clipboard.
-        // and only show our snackbar when Android will not show an indication by default.                 *
-        // See https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications).
-        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
-            appStore.dispatch(ShareAction.CopyLinkToClipboard)
+        if (isPrivate) {
+            clipData.description.extras = PersistableBundle().apply {
+                putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true)
+            }
         }
+
+        clipboardManager.setPrimaryClip(clipData)
     }
 
     companion object {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt
index 621e8e1f643..29585937137 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt
@@ -17,9 +17,11 @@ import androidx.annotation.VisibleForTesting
 import androidx.core.graphics.drawable.toDrawable
 import androidx.core.view.isVisible
 import mozilla.components.browser.state.selector.findCustomTab
+import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
 import mozilla.components.browser.state.selector.selectedTab
 import mozilla.components.browser.state.store.BrowserStore
 import mozilla.components.support.base.log.logger.Logger
+import mozilla.components.support.utils.ClipboardHandler
 import mozilla.telemetry.glean.private.NoExtras
 import org.mozilla.fenix.GleanMetrics.Events
 import org.mozilla.fenix.R
@@ -83,30 +85,7 @@ object ToolbarPopupWindow {
         binding.pasteAndGo.isVisible = containsUrl && !isCustomTabSession
 
         if (copyVisible) {
-            binding.copy.setOnClickListener { copyView ->
-                popupWindow.dismiss()
-                clipboard.text = getUrlForClipboard(
-                    copyView.context.components.core.store,
-                    customTabId,
-                )
-
-                // Android 13+ shows by default a popup for copied text.
-                // Avoid overlapping popups informing the user when the URL is copied to the clipboard.
-                // and only show our snackbar when Android will not show an indication by default.                 *
-                // See https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications).
-                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
-                    snackbarParent.get()?.let { snackbarParent ->
-                        Snackbar.make(
-                            snackBarParentView = snackbarParent,
-                            snackbarState = SnackbarState(
-                                message = context.getString(R.string.browser_toolbar_url_copied_to_clipboard_snackbar),
-                                duration = SnackbarState.Duration.Preset.Long,
-                            ),
-                        ).show()
-                    }
-                }
-                Events.copyUrlTapped.record(NoExtras())
-            }
+            setupCopyButton(binding, popupWindow, clipboard, customTabId, snackbarParent, context)
         }
 
         if (binding.paste.isVisible) {
@@ -139,6 +118,42 @@ object ToolbarPopupWindow {
         }
     }
 
+    private fun setupCopyButton(
+        binding: BrowserToolbarPopupWindowBinding,
+        popupWindow: PopupWindow,
+        clipboard: ClipboardHandler,
+        customTabId: String?,
+        snackbarParent: WeakReference<ViewGroup>,
+        context: Context,
+    ) {
+        binding.copy.setOnClickListener { copyView ->
+            popupWindow.dismiss()
+            val store = copyView.context.components.core.store
+            val url = getUrlForClipboard(store, customTabId)
+            if (isPrivateTab(store, customTabId)) {
+                clipboard.sensitiveText = url
+            } else {
+                clipboard.text = url
+            }
+            // Android 13+ shows by default a popup for copied text.
+            // Avoid overlapping popups informing the user when the URL is copied to the clipboard.
+            // and only show our snackbar when Android will not show an indication by default.
+            // See https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications).
Loading diff…