CVE-2024-26131: Insufficient Information (NVD-CWE-noinfo)
value: Element Android is an Android Matrix Client. Element Android version 1.4.3 through 1.6.10 is vulnerable to intent redirection, allowing a third-party malicious application to start any internal activity by passing some extra parameters. Possible impact includes making Element Android display an arbitrary web page, executing arbitrary JavaScript; bypassing PIN code protection; and account takeover by spawning a login screen to send credentials to an arbitrary home server. This issue is fixed in Element Android 1.6.12. There is no known workaround to mitigate the issue.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-02-29T01:44Z
Repository: https://github.com/element-hq/element-android
Language: Other
Files changed: changelog.d/+check-intent.bugfix, vector/src/main/java/im/vector/app/features/MainActivity.kt
Commit date: 2024-02-16 11:51:16 +0100
Commit message: Add a check on incoming intent.

Diff: diff --git a/changelog.d/+check-intent.bugfix b/changelog.d/+check-intent.bugfix
new file mode 100644
index 0000000000..728ae13275
--- /dev/null
+++ b/changelog.d/+check-intent.bugfix
@@ -0,0 +1 @@
+Add a check on incoming intent.
diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt
index c8aa108ccb..0f0ac83903 100644
--- a/vector/src/main/java/im/vector/app/features/MainActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt
@@ -37,10 +37,13 @@ import im.vector.app.core.utils.deleteAllFiles
 import im.vector.app.databinding.ActivityMainBinding
 import im.vector.app.features.analytics.VectorAnalytics
 import im.vector.app.features.analytics.plan.ViewRoom
 import im.vector.app.features.home.HomeActivity
 import im.vector.app.features.home.ShortcutsHandler
+import im.vector.app.features.home.room.detail.RoomDetailActivity
+import im.vector.app.features.home.room.threads.ThreadsActivity
+import im.vector.app.features.location.live.map.LiveLocationMapViewActivity
 import im.vector.app.features.notifications.NotificationDrawerManager
 import im.vector.app.features.pin.UnlockedActivity
 import im.vector.app.features.pin.lockscreen.crypto.LockScreenKeyRepository
 import im.vector.app.features.pin.lockscreen.pincode.PinCodeHelper
 import im.vector.app.features.popup.PopupAlertManager
@@ -113,10 +116,18 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
             return Intent(context, MainActivity::class.java).apply {
                 action = ACTION_ROOM_DETAILS_FROM_SHORTCUT
                 putExtra(EXTRA_ROOM_ID, roomId)
             }
         }
+
+        val allowList = listOf(
+                HomeActivity::class.java.name,
+                MainActivity::class.java.name,
+                RoomDetailActivity::class.java.name,
+                ThreadsActivity::class.java.name,
+                LiveLocationMapViewActivity::class.java.name,
+        )
     }
 
     private val startAppViewModel: StartAppViewModel by viewModel()
 
     override fun getBinding() = ActivityMainBinding.inflate(layoutInflater)
@@ -184,10 +195,11 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
 
         if (intent.hasExtra(EXTRA_NEXT_INTENT)) {
             // Start the next Activity
             startSyncing()
             val nextIntent = intent.getParcelableExtraCompat<Intent>(EXTRA_NEXT_INTENT)
+                    ?.takeIf { it.isValid() }
             startIntentAndFinish(nextIntent)
         } else if (intent.hasExtra(EXTRA_INIT_SESSION)) {
             startSyncing()
             setResult(RESULT_OK)
             finish()
@@ -378,6 +390,13 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
 
     private fun startIntentAndFinish(intent: Intent?) {
         intent?.let { startActivity(it) }
         finish()
     }
+
+    private fun Intent.isValid(): Boolean {
+        val componentName = resolveActivity(packageManager) ?: return false
+        val packageName = componentName.packageName
+        val className = componentName.className
+        return packageName == buildMeta.applicationId && className in allowList
+    }
 }

Fixed code: Add a check on incoming intent.
import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.home.room.threads.ThreadsActivity
import im.vector.app.features.location.live.map.LiveLocationMapViewActivity

        val allowList = listOf(
                HomeActivity::class.java.name,
                MainActivity::class.java.name,
                RoomDetailActivity::class.java.name,
                ThreadsActivity::class.java.name,
                LiveLocationMapViewActivity::class.java.name,
        )
                    ?.takeIf { it.isValid() }

    private fun Intent.isValid(): Boolean {
        val componentName = resolveActivity(packageManager) ?: return false
        val packageName = componentName.packageName
        val className = componentName.className
        return packageName == buildMeta.applicationId && className in allowList
    }