CVE-2021-4438 (published 2024-04-07T09:15Z)

A vulnerability, which was classified as critical, has been found in kyivstarteam react-native-sms-user-consent up to 1.1.4 on Android. Affected by this issue is the function registerReceiver of the file android/src/main/java/ua/kyivstar/reactnativesmsuserconsent/SmsUserConsentModule.kt. The manipulation leads to improper export of android application components. Attacking locally is a requirement. Upgrading to version 1.1.5 is able to address this issue. The name of the patch is 5423dcb0cd3e4d573b5520a71fa08aa279e4c3c7. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-259508.


Weakness information:
cwe_id: CWE-926
cwe_name: Improper Export of Android Application Components
description: The Android application exports a component for use by other applications, but does not properly restrict which applications can launch the component or access the data it contains.
extended_description: 
            The attacks and consequences of improperly exporting a component may depend on the exported component:
               
                  If access to an exported Activity is not restricted, any application will be able to launch the activity. This may allow a malicious application to gain access to sensitive information, modify the internal state of the application, or trick a user into interacting with the victim application while believing they are still interacting with the malicious application.
                  If access to an exported Service is not restricted, any application may start and bind to the Service. Depending on the exposed functionality, this may allow a malicious application to perform unauthorized actions, gain access to sensitive information, or corrupt the internal state of the application.
                  If access to a Content Provider is not restricted to only the expected applications, then malicious applications might be able to access the sensitive data. Note that in Android before 4.2, the Content Provider is automatically exported unless it has been explicitly declared as NOT exported.
               
         
         

Fix information:
repo_url: https://github.com/kyivstarteam/react-native-sms-user-consent
commit_details: repo_url: https://github.com/kyivstarteam/react-native-sms-user-consent
author: Simonas Gildutis
author_date: 2021-04-23 11:26:49+03:00
msg: Remediation for Intent Redirection Vulnerability (#4)

* Update build.gradle

* Small refactor

* Update SmsUserConsentPackage.kt

* Add permission to registerReceiver

SmsRetriever.SEND_PERMISSION should be included to remedy Intent Redirection Vulnerability

* guard against null intents
repository: repo_url: https://github.com/kyivstarteam/react-native-sms-user-consent
repo_name: kyivstarteam/react-native-sms-user-consent
repo_language: Java
owner: kyivstarteam
file_changes: filename: build.gradle
change_type: ModificationType.MODIFY
diff: @@ -128,5 +128,5 @@ dependencies {
   api 'com.facebook.react:react-native:+'
   implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
   implementation "com.google.android.gms:play-services-auth:17.0.0"
-  implementation "com.google.android.gms:play-services-auth-api-phone:17.1.0"
+  implementation "com.google.android.gms:play-services-auth-api-phone:17.4.0"
 }

programming_language: JavaScript
filename: SmsRetrieveBroadcastReceiver.kt
change_type: ModificationType.MODIFY
diff: @@ -10,21 +10,17 @@ import com.google.android.gms.auth.api.phone.SmsRetriever;
 import com.google.android.gms.common.api.CommonStatusCodes;
 import com.google.android.gms.common.api.Status;
 
-
-
 class SmsRetrieveBroadcastReceiver(currentActivity: Activity?): BroadcastReceiver() {
-
-
   val SMS_CONSENT_REQUEST = 1244
 
   private var activity: Activity? = currentActivity
 
   override fun onReceive(context: Context?, intent: Intent) {
-    if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.action)) {
-      val extras = intent.extras
+    val extras = intent.extras
+    if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action && extras != null) {
       val smsRetrieverStatus: Status = extras[SmsRetriever.EXTRA_STATUS] as Status
-      val statusCode: Int = smsRetrieverStatus.getStatusCode()
-      when (statusCode) {
+      
+      when (smsRetrieverStatus.statusCode) {
         CommonStatusCodes.SUCCESS ->                     // Get consent intent
           try {
             val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)

programming_language: Scala
filename: SmsUserConsentModule.kt
change_type: ModificationType.MODIFY
diff: @@ -36,30 +36,25 @@ class SmsUserConsentModule(reactContext: ReactApplicationContext) : ReactContext
     this.promise = promise
     if (reactContext?.currentActivity != null) {
       val task: Task<Void> = SmsRetriever.getClient(reactContext.currentActivity!!).startSmsUserConsent(null)
-      task.addOnSuccessListener(object : OnSuccessListener<Void?> {
-        override fun onSuccess(aVoid: Void?) {
-          // successfully started an SMS Retriever for one SMS message
-          registerReceiver()
-        }
-      })
-      task.addOnFailureListener(object : OnFailureListener {
-        override fun onFailure(e: Exception) {
-          promise.reject(E_OTP_ERROR, e)
-        }
-      })
+
+      task.addOnSuccessListener { // successfully started an SMS Retriever for one SMS message
+        registerReceiver()
+      }
+      task.addOnFailureListener { e -> promise.reject(E_OTP_ERROR, e) }
     }
   }
 
   @ReactMethod
   fun removeOTPListener() {
     unregisterReceiver()
+    promise = null
   }
 
   private fun registerReceiver() {
     if (reactContext?.currentActivity != null) {
       receiver = SmsRetrieveBroadcastReceiver(reactContext.currentActivity)
       val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
-      reactContext.currentActivity?.registerReceiver(receiver, intentFilter)
+      reactContext.currentActivity?.registerReceiver(receiver, intentFilter, SmsRetriever.SEND_PERMISSION, null)
     }
   }
 
@@ -75,9 +70,9 @@ class SmsUserConsentModule(reactContext: ReactApplicationContext) : ReactContext
       when (requestCode) {
         SMS_CONSENT_REQUEST -> {
           unregisterReceiver()
-          if (resultCode == RESULT_OK) {
+          if (resultCode == RESULT_OK  && intent != null) {
             // Get SMS message content
-            val message = intent?.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
+            val message = intent.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
             val map = Arguments.createMap()
             map.putString(RECEIVED_OTP_PROPERTY, message)
             promise?.resolve(map)

programming_language: Scala
filename: SmsUserConsentPackage.kt
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,5 @@
 package ua.kyivstar.reactnativesmsuserconsent
 
-import java.util.Arrays
-
 import com.facebook.react.ReactPackage
 import com.facebook.react.bridge.NativeModule
 import com.facebook.react.bridge.ReactApplicationContext
@@ -9,7 +7,7 @@ import com.facebook.react.uimanager.ViewManager
 
 class SmsUserConsentPackage : ReactPackage {
     override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
-        return Arrays.asList<NativeModule>(SmsUserConsentModule(reactContext))
+        return listOf<NativeModule>(SmsUserConsentModule(reactContext))
     }
 
     override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {

programming_language: Scala