Medium firefox Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionOn Android, Firefox may have inadvertently allowed viewing saved passwords without the required device PIN authentication.
ComponentCore
Bug ClassLogic Error
Tracker1928779
Fix commit24e70ab57d0e (firefox) +51/-23
CISA KEVNot listed
CreditedMultiple Reporters
Disclosed2024-11-26

Changed Functions

FunctionChangeNotes
VisibilityLifecycleObserver
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/lifecycle/VisibilityLifecycleObserver.kt
modified
if
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
modified
if
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt
modified
if
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt
modified

Files Changed

  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BiometricAuthenticationManager.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/lifecycle/VisibilityLifecycleObserver.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt
  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BiometricAuthenticationManager.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BiometricAuthenticationManager.kt
index 94ca4218989..88212360b42 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BiometricAuthenticationManager.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/BiometricAuthenticationManager.kt
@@ -12,9 +12,11 @@ object BiometricAuthenticationManager {
 }
 
 /**
- * Data class containing the boolean that dictates the need of displaying the
- * biometric authentication prompt
+ * Data class containing a boolean that dictates the need of displaying the
+ * biometric authentication prompt and another boolean about the biometric authentication
+ * being successful or not
  */
 data class BiometricAuthenticationNeededInfo(
-    var shouldAuthenticate: Boolean = true,
+    var shouldShowAuthenticationPrompt: Boolean = true,
+    var authenticated: Boolean = false,
 )
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/lifecycle/VisibilityLifecycleObserver.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/lifecycle/VisibilityLifecycleObserver.kt
index 99522b207e3..08962ba5a85 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/lifecycle/VisibilityLifecycleObserver.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/lifecycle/VisibilityLifecycleObserver.kt
@@ -15,6 +15,8 @@ import org.mozilla.fenix.BiometricAuthenticationManager
 class VisibilityLifecycleObserver : DefaultLifecycleObserver {
     override fun onPause(owner: LifecycleOwner) {
         super.onPause(owner)
-        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate = true
+        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
+            true
+        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = false
     }
 }
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt
index 334377ead15..90de5de9db9 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/AddLoginFragment.kt
@@ -382,7 +382,8 @@ class AddLoginFragment : Fragment(R.layout.fragment_add_login), MenuProvider {
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
-        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate = false
+        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
+            false
     }
 
     companion object {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
index 807d46e25a5..132e86dae3c 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/EditLoginFragment.kt
@@ -72,8 +72,9 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login), MenuProvider {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         startForResult = registerForActivityResult {
-            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate =
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
                 false
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = true
             setSecureContentVisibility(true)
         }
     }
@@ -330,17 +331,23 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login), MenuProvider {
 
     override fun onResume() {
         super.onResume()
-        if (BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate) {
-            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate =
+        if (BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt) {
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
                 false
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = false
             setSecureContentVisibility(false)
+
             bindBiometricsCredentialsPromptOrShowWarning(
                 view = requireView(),
                 onShowPinVerification = { intent -> startForResult.launch(intent) },
-                onAuthSuccess = { setSecureContentVisibility(true) },
+                onAuthSuccess = {
+                    BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated =
+                        true
+                    setSecureContentVisibility(true)
+                },
             )
         } else {
-            setSecureContentVisibility(true)
+            setSecureContentVisibility(BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated)
         }
     }
 
@@ -362,7 +369,7 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login), MenuProvider {
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
-        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate = false
+        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt = false
     }
 
     private fun setSecureContentVisibility(isVisible: Boolean) {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt
index 1cc3cf96ad4..2e85971acf8 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt
@@ -82,8 +82,9 @@ class LoginDetailFragment : SecureFragment(R.layout.fragment_login_detail), Menu
         _binding = FragmentLoginDetailBinding.bind(view)
 
         startForResult = registerForActivityResult {
-            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate =
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
                 false
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = true
             setSecureContentVisibility(true)
         }
 
@@ -139,17 +140,23 @@ class LoginDetailFragment : SecureFragment(R.layout.fragment_login_detail), Menu
 
     override fun onResume() {
         super.onResume()
-        if (BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate) {
-            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate =
+        if (BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt) {
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
                 false
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = false
             setSecureContentVisibility(false)
+
             bindBiometricsCredentialsPromptOrShowWarning(
                 view = requireView(),
                 onShowPinVerification = { intent -> startForResult.launch(intent) },
-                onAuthSuccess = { setSecureContentVisibility(true) },
+                onAuthSuccess = {
+                    BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated =
+                        true
+                    setSecureContentVisibility(true)
+                },
             )
         } else {
-            setSecureContentVisibility(true)
+            setSecureContentVisibility(BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated)
         }
     }
 
@@ -274,7 +281,7 @@ class LoginDetailFragment : SecureFragment(R.layout.fragment_login_detail), Menu
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
-        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate = false
+        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt = false
     }
 
     private fun setSecureContentVisibility(isVisible: Boolean) {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt
index 7b506d052d2..20d9564084c 100644
--- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt
+++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt
@@ -78,24 +78,32 @@ class SavedLoginsFragment : SecureFragment(), MenuProvider {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         startForResult = registerForActivityResult {
-            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate =
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
                 false
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = true
             setSecureContentVisibility(true)
         }
     }
 
     override fun onResume() {
         super.onResume()
-        if (BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate) {
-            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate = false
+        if (BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt) {
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt =
+                false
+            BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = false
             setSecureContentVisibility(false)
+
             bindBiometricsCredentialsPromptOrShowWarning(
                 view = requireView(),
                 onShowPinVerification = { intent -> startForResult.launch(intent) },
-                onAuthSuccess = { setSecureContentVisibility(true) },
+                onAuthSuccess = {
+                    BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated =
+                        true
+                    setSecureContentVisibility(true)
+                },
             )
         } else {
-            setSecureContentVisibility(true)
+            setSecureContentVisibility(BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated)
         }
         initToolbar()
     }
@@ -109,7 +117,8 @@ class SavedLoginsFragment : SecureFragment(), MenuProvider {
 
         _binding = FragmentSavedLoginsBinding.bind(view)
         setSecureContentVisibility(false)
-        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldAuthenticate = true
+        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.shouldShowAuthenticationPrompt = true
+        BiometricAuthenticationManager.biometricAuthenticationNeededInfo.authenticated = false
Loading diff…