Android URI Permission Manipulation

ID

kotlin.android_uri_permission_manipulation

Severity

high

Resource

Injection

Language

Kotlin

Tags

CWE:266, NIST.SP.800-53, PCI-DSS:6.5.6, android

Description

Android URI Permission Manipulation occurs when user-provided Intents are returned using setResult without proper validation, potentially granting unintended access to content providers.

Rationale

When an Android component expects a result from an Activity, it uses startActivityForResult. The started Activity can return data to the calling component via setResult. If an Activity directly returns a user-provided Intent without checks, it may inadvertently allow access to non-exported content providers configured with android:grantUriPermissions="true". Malicious apps can exploit this by adding URI permission flags to Intents.

Consider the following Kotlin example:

class IntentUriPermissionManipulation : Activity() {

    // BAD: the user-provided Intent is returned as-is
    fun dangerous() {
        val incomingIntent = intent
        incomingIntent.putExtra("result", "resultData")
        setResult(RESULT_OK, incomingIntent)
    }

    // GOOD: a new Intent is created and returned
    fun safe() {
        val newIntent = Intent().apply {
            putExtra("result", "resultData")
        }
        setResult(RESULT_OK, newIntent)
    }

    // GOOD: the user-provided Intent is sanitized before being returned
    fun sanitized() {
        val incomingIntent = intent.apply {
            putExtra("result", "resultData")
            removeFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }
        setResult(RESULT_OK, incomingIntent)
    }
}

Remediation

To protect against URI permission manipulation, avoid returning untrusted Intents via setResult. Instead, use new or sanitized Intents.

Practical Remediation Steps for Kotlin:

  1. Create New Intents: Always create new Intents when returning data with setResult. Avoid using user-provided Intents directly.

  2. Sanitize Incoming Intents: If you must use a received Intent, ensure it does not contain URI permission flags. Use Intent.removeFlags to remove them if necessary.

References