CVE-2021-41094: Other (NVD-CWE-Other)
value: Wire is an open source secure messenger. Users of Wire by Bund may bypass the mandatory encryption at rest feature by simply disabling their device passcode. Upon launching, the app will attempt to enable encryption at rest by generating encryption keys via the Secure Enclave, however it will fail silently if no device passcode is set. The user has no indication that encryption at rest is not active since the feature is hidden to them. This issue has been resolved in version 3.70
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
CVSS v3 base score: 4.6
Published: 2021-10-04T19:15Z
Repository: https://github.com/wireapp/wire-ios
Language: Swift
Files changed: Wire-iOS/Generated/Strings+Generated.swift, Wire-iOS/Resources/Base.lproj/Localizable.strings, Wire-iOS/Sources/AppRootRouter.swift
Commit date: 2021-04-16 11:00:50 +0200
Commit message: Merge pull request from GHSA-h4m7-pr8h-j7rf

* Show alert when logged out due to missing biometric passcode

* Update copy

* Revert strings file change

* Update copy
Diff: diff --git a/Wire-iOS/Generated/Strings+Generated.swift b/Wire-iOS/Generated/Strings+Generated.swift
index c66d19719..a87c21852 100644
--- a/Wire-iOS/Generated/Strings+Generated.swift
+++ b/Wire-iOS/Generated/Strings+Generated.swift
@@ -55,10 +55,16 @@ internal enum L10n {
       internal enum Website {
         /// Wire Website
         internal static let title = L10n.tr("Localizable", "about.website.title")
       }
     }
+    internal enum AccountDeletedMissingPasscodeAlert {
+      /// In order to use Wire, please set a passcode in your device settings.
+      internal static let message = L10n.tr("Localizable", "account_deleted_missing_passcode_alert.message")
+      /// No Device Passcode
+      internal static let title = L10n.tr("Localizable", "account_deleted_missing_passcode_alert.title")
+    }
     internal enum AccountDeletedSessionExpiredAlert {
       /// The application did not communicate with the server for a long period of time, or your session has been remotely invalidated.
       internal static let message = L10n.tr("Localizable", "account_deleted_session_expired_alert.message")
       /// Your session expired
       internal static let title = L10n.tr("Localizable", "account_deleted_session_expired_alert.title")
diff --git a/Wire-iOS/Resources/Base.lproj/Localizable.strings b/Wire-iOS/Resources/Base.lproj/Localizable.strings
index 2eaf623d7..e34e34e88 100644
--- a/Wire-iOS/Resources/Base.lproj/Localizable.strings
+++ b/Wire-iOS/Resources/Base.lproj/Localizable.strings
@@ -1802,10 +1802,13 @@
 
 // Account deleted alert
 "account_deleted_session_expired_alert.title" = "Your session expired";
 "account_deleted_session_expired_alert.message" = "The application did not communicate with the server for a long period of time, or your session has been remotely invalidated.";
 
+"account_deleted_missing_passcode_alert.title" = "No device passcode";
+"account_deleted_missing_passcode_alert.message" = "In order to use Wire, please set a passcode in your device settings.";
+
 // Button cell state
 "button_message_cell.state.unselected" = "unselected";
 "button_message_cell.state.selected" = "selected";
 "button_message_cell.state.confirmed" = "confirmed";
 
diff --git a/Wire-iOS/Sources/AppRootRouter.swift b/Wire-iOS/Sources/AppRootRouter.swift
index 6428cf2fe..1fabee257 100644
--- a/Wire-iOS/Sources/AppRootRouter.swift
+++ b/Wire-iOS/Sources/AppRootRouter.swift
@@ -443,12 +443,18 @@ extension AppRootRouter {
             return
         }
 
         switch reason {
         case .sessionExpired:
-            rootViewController.presentAlertWithOKButton(title: "account_deleted_session_expired_alert.title".localized,
-                                                        message: "account_deleted_session_expired_alert.message".localized)
+            rootViewController.presentAlertWithOKButton(
+                title: L10n.Localizable.AccountDeletedSessionExpiredAlert.title,
+                message: L10n.Localizable.AccountDeletedSessionExpiredAlert.message)
+
+        case .biometricPasscodeNotAvailable:
+            rootViewController.presentAlertWithOKButton(
+                title: L10n.Localizable.AccountDeletedMissingPasscodeAlert.title,
+                message: L10n.Localizable.AccountDeletedMissingPasscodeAlert.message)
 
         case .databaseWiped:
             let wipeCompletionViewController = WipeCompletionViewController()
             wipeCompletionViewController.modalPresentationStyle = .fullScreen
             rootViewController.present(wipeCompletionViewController, animated: true)

Vulnerable code:             rootViewController.presentAlertWithOKButton(title: "account_deleted_session_expired_alert.title".localized,
                                                        message: "account_deleted_session_expired_alert.message".localized)
Fixed code:     internal enum AccountDeletedMissingPasscodeAlert {
      /// In order to use Wire, please set a passcode in your device settings.
      internal static let message = L10n.tr("Localizable", "account_deleted_missing_passcode_alert.message")
      /// No Device Passcode
      internal static let title = L10n.tr("Localizable", "account_deleted_missing_passcode_alert.title")
    }
"account_deleted_missing_passcode_alert.title" = "No device passcode";
"account_deleted_missing_passcode_alert.message" = "In order to use Wire, please set a passcode in your device settings.";

            rootViewController.presentAlertWithOKButton(
                title: L10n.Localizable.AccountDeletedSessionExpiredAlert.title,
                message: L10n.Localizable.AccountDeletedSessionExpiredAlert.message)

        case .biometricPasscodeNotAvailable:
            rootViewController.presentAlertWithOKButton(
                title: L10n.Localizable.AccountDeletedMissingPasscodeAlert.title,
                message: L10n.Localizable.AccountDeletedMissingPasscodeAlert.message)