androidkotlingoogle-playbroadcastreceiverandroid-security

SmsBroadcastReceiver Intent Redirection Error


When I'm trying to publish my app on play store but im getting the intent redirection error in my broadcast receiver. Here is the related code.


class SmsBroadcastReceiver : BroadcastReceiver() {

    var smsBroadcastReceiverListener: SmsBroadcastReceiverListener? = null

    override fun onReceive(context: Context?, intent: Intent?) {

        if (intent?.action == SmsRetriever.SMS_RETRIEVED_ACTION) {

            val extras = intent.extras
            val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status

            when (smsRetrieverStatus.statusCode) {
                CommonStatusCodes.SUCCESS -> {

                    val messageIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
                    smsBroadcastReceiverListener?.onSuccess(messageIntent)
                }
                CommonStatusCodes.TIMEOUT -> {
                    smsBroadcastReceiverListener?.onFailure()
                }
            }
        }
    }

    /**
     * Sms Broadcast Receiver Listener
     */
    interface SmsBroadcastReceiverListener {
        /**
         * if common status success
         */
        fun onSuccess(intent: Intent?)
        /**
         * if common status timeout
         */
        fun onFailure()
    }
}

And here is my manifest file for my broadcast

        <receiver
            android:name=".broadcast.SmsBroadcastReceiver"
            android:exported="false"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

I couldn't find a solution can someone help ?

Tried to change my manifest file but it looks fine to me. Probably the problem is about my onReceive function but couldn't find a solution atm.


Solution

  • class SmsBroadcastReceiver : BroadcastReceiver() {
    
    var smsBroadcastReceiverListener: SmsBroadcastReceiverListener? = null
    
    override fun onReceive(context: Context?, intent: Intent?) {
        // Verify the intent action
        if (intent?.action == SmsRetriever.SMS_RETRIEVED_ACTION) {
            val extras: Bundle? = intent.extras
            val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as? Status
    
            // Validate the status is from the expected sender
            if (smsRetrieverStatus != null) {
                when (smsRetrieverStatus.statusCode) {
                    CommonStatusCodes.SUCCESS -> {
                        val messageIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
    
                        // Validate the nested intent
                        if (validateIntent(context, messageIntent)) {
                            smsBroadcastReceiverListener?.onSuccess(messageIntent)
                        } else {
                            Log.w("SmsBroadcastReceiver", "Untrusted intent detected")
                        }
                    }
                    CommonStatusCodes.TIMEOUT -> {
                        smsBroadcastReceiverListener?.onFailure()
                    }
                    else -> {
                        Log.w("SmsBroadcastReceiver", "Unexpected status code: ${smsRetrieverStatus.statusCode}")
                    }
                }
            } else {
                Log.w("SmsBroadcastReceiver", "SmsRetriever status is null")
            }
        } else {
            Log.w("SmsBroadcastReceiver", "Unexpected intent action: ${intent?.action}")
        }
    }
    
    // Validate the nested intent
    private fun validateIntent(context: Context?, intent: Intent?): Boolean {
        if (context == null || intent == null) return false
    
        // Check if the nested intent grants URI permissions
        val flags = intent.flags
        if ((flags and Intent.FLAG_GRANT_READ_URI_PERMISSION != 0) ||
            (flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION != 0)) {
            return false
        }
    
        // Ensure the nested intent is not harmful
        val componentName = intent.resolveActivity(context.packageManager)
        Log.d("SmsBroadcastReceiver", "Resolved ComponentName: $componentName")
    
        // Check if the intent comes from a trusted package
        val isValid = componentName?.packageName == "com.google.android.gms"
        Log.d("SmsBroadcastReceiver", "isValid: $isValid")
    
        return isValid
    }
    
    /**
     * Sms Broadcast Receiver Listener
     */
    interface SmsBroadcastReceiverListener {
        /**
         * if common status success
         */
        fun onSuccess(intent: Intent?)
    
        /**
         * if common status timeout
         */
        fun onFailure()
    } }