Skip to content

Commit

Permalink
[BWA-10] Sanitize launch intents before processing (#128)
Browse files Browse the repository at this point in the history
  • Loading branch information
SaintPatrck authored Jun 14, 2024
1 parent 7ca1eab commit f912e00
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 5 deletions.
18 changes: 13 additions & 5 deletions app/src/main/kotlin/com/bitwarden/authenticator/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.bitwarden.authenticator

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.WindowManager
import androidx.activity.compose.setContent
import androidx.activity.viewModels
Expand All @@ -11,6 +10,7 @@ import androidx.compose.runtime.getValue
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.bitwarden.authenticator.data.platform.util.isSuspicious
import com.bitwarden.authenticator.ui.platform.feature.rootnav.RootNavScreen
import com.bitwarden.authenticator.ui.platform.theme.AuthenticatorTheme
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -23,6 +23,7 @@ class MainActivity : AppCompatActivity() {
private val mainViewModel: MainViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
sanitizeIntent()
var shouldShowSplashScreen = true
installSplashScreen().setKeepOnScreenCondition { shouldShowSplashScreen }
super.onCreate(savedInstanceState)
Expand Down Expand Up @@ -53,18 +54,26 @@ class MainActivity : AppCompatActivity() {

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
sanitizeIntent()
mainViewModel.trySendAction(
MainAction.ReceiveNewIntent(intent = intent)
)
}

private fun sanitizeIntent() {
if (intent.isSuspicious) {
intent = Intent(
/* packageContext = */ this,
/* cls = */ MainActivity::class.java,
)
}
}

private fun observeViewModelEvents() {
Log.d("TAG", "observeViewModelEvents() called")
mainViewModel
.eventFlow
.onEach { event ->
Log.d("TAG", "observeViewModelEvents: onEach $event")
when(event) {
when (event) {
is MainEvent.ScreenCaptureSettingChange -> {
handleScreenCaptureSettingChange(event)
}
Expand All @@ -74,7 +83,6 @@ class MainActivity : AppCompatActivity() {
}

private fun handleScreenCaptureSettingChange(event: MainEvent.ScreenCaptureSettingChange) {
Log.d("TAG", "handleScreenCaptureSettingChange() called with: event = $event")
if (event.isAllowed) {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.bitwarden.authenticator.data.platform.util

import android.content.Intent

/**
* Returns true if this intent contains unexpected or suspicious data.
*/
val Intent.isSuspicious: Boolean
get() {
val containsSuspiciousExtras = extras?.isEmpty?.not() ?: false
val containsSuspiciousData = data != null
return containsSuspiciousData || containsSuspiciousExtras
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.bitwarden.authenticator.data.platform.util

import android.content.Intent
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

class IntentExtensionsTest {
@Test
fun `isSuspicious should return true when extras are not empty`() {
val intent = mockk<Intent> {
every { data } returns mockk()
every { extras } returns mockk {
every { isEmpty } returns false
}
}

assertTrue(intent.isSuspicious)
}

@Test
fun `isSuspicious should return true when extras are null`() {
val intent = mockk<Intent> {
every { data } returns mockk()
every { extras } returns null
}

assertTrue(intent.isSuspicious)
}

@Test
fun `isSuspicious should return true when data is not null`() {
val intent = mockk<Intent> {
every { data } returns mockk()
every { extras } returns null
}

assertTrue(intent.isSuspicious)
}

@Test
fun `isSuspicious should return false when data and extras are null`() {
val intent = mockk<Intent> {
every { data } returns null
every { extras } returns null
}

assertFalse(intent.isSuspicious)
}

@Test
fun `isSuspicious should return false when data is null and extras are empty`() {
val intent = mockk<Intent> {
every { data } returns null
every { extras } returns mockk {
every { isEmpty } returns true
}
}

assertFalse(intent.isSuspicious)
}
}

0 comments on commit f912e00

Please sign in to comment.