Too Broad App Permissions

ID

kotlin.android_too_broad_permissions

Severity

low

Resource

Access Control

Language

Kotlin

Tags

CWE:250, CWE:269, CWE:732, MASVS:MSTG-PLATFORM-1, OWASP:2021:M1, android, permissions

Description

Android applications should follow the principle of least privilege by requesting only the minimum permissions necessary for their core functionality. Excessive permissions increase the attack surface, enable privacy violations, and may lead to app rejection from Google Play Store.

Rationale

Detecting excessive permissions helps prevent multiple security and privacy issues.

Execution with Unnecessary Privileges (CWE-250):

Applications requesting more permissions than needed create opportunities for:

  • Privilege escalation through compromised components

  • Increased impact of vulnerabilities (e.g., XSS with storage access becomes data theft)

  • Malware abuse of granted permissions

  • Unauthorized access to sensitive resources

Improper Privilege Management (CWE-269):

Permission mismanagement manifests in several patterns:

  • Critical permissions enabling malware capabilities (accessibility services, overlay windows)

  • Broad access permissions bypassing scoped security controls

  • Deprecated permissions when modern alternatives exist

  • Privacy-sensitive permissions without user-controlled alternatives

Google Play Policy Compliance:

Google Play Store enforces strict permission policies, rejecting apps that:

  • Request permissions unnecessary for core functionality

  • Use deprecated permissions on modern API levels

  • Access photos/videos without using Photo Picker API (enforced 2025)

  • Request SMS/Call Log permissions without being default handler apps

This detector identifies excessive permissions across four severity tiers:

  • TIER 1: Critical Permissions (Malware Indicators)

Dangerous permissions commonly abused by malware:

<!-- VULNERABLE: Accessibility service - 100% banking trojan usage -->
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>

<!-- VULNERABLE: Overlay windows - 74% ransomware usage -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

<!-- VULNERABLE: Device admin - prevents uninstallation -->
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN"/>

<!-- VULNERABLE: Silent app installation -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

<!-- VULNERABLE: Usage tracking/surveillance -->
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
  • TIER 2: Broad Access Permissions

Permissions granting unrestricted system access:

<!-- VULNERABLE: All files access (bypasses scoped storage) -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

<!-- VULNERABLE: Modify system settings -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

<!-- VULNERABLE: Modify secure system settings -->
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
  • TIER 3: Deprecated Permissions

Legacy permissions replaced by scoped alternatives:

<manifest>
    <uses-sdk android:targetSdkVersion="33"/>

    <!-- VULNERABLE: Deprecated on API 29+ -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <!-- VULNERABLE: Deprecated on API 33+ -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <!-- VULNERABLE: Deprecated on API 31+ -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <!-- VULNERABLE: Deprecated on API 31+ -->
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
</manifest>
  • TIER 4: Privacy-Sensitive Permissions with Alternatives

Permissions where privacy-preserving APIs exist:

<!-- VULNERABLE: SMS access has permission-free alternative -->
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

<!-- VULNERABLE: Location - consider coarse instead of fine -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<!-- VULNERABLE: Contacts - picker API available -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>

<!-- VULNERABLE: Camera - request at runtime only -->
<uses-permission android:name="android.permission.CAMERA"/>

Research on Android malware families shows specific permission patterns. For example, banking trojans often use accessibility permissions:

<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
<uses-permission android:name="android.permission.READ_SMS"/> <!-- OTP interception -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <!-- Phishing overlays -->

On the other hand, ransomware use overlay windows along with device admin:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN"/>

Stalkerware / Spyware often combine permissions for exfiltrating sensitive information:

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Remediation

  1. Remove Unnecessary Permissions

    Audit all requested permissions and remove those not essential to core functionality:

    <!-- DON'T: Excessive permissions for a photo sharing app -->
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
    <!-- DO: Minimal permissions with modern APIs -->
    <!-- Use Photo Picker API - no permission required -->
    <!-- Use CameraX with runtime permission request -->
    <!-- Location only if core feature, prefer COARSE -->
  2. Migrate to Modern APIs

    • Storage Access (API 29+):

      // DON'T: Deprecated broad storage access
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
      
      // DO: Use Scoped Storage and Photo Picker
      ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
          registerForActivityResult(new PickVisualMedia(), uri -> {
              // Handle selected photo (no permission required)
          });
      pickMedia.launch(new PickVisualMediaRequest.Builder()
          .setMediaType(PickVisualMedia.ImageOnly.INSTANCE)
          .build());
    • SMS/OTP Verification:

      // DON'T: Request SMS permissions
      <uses-permission android:name="android.permission.READ_SMS"/>
      
      // DO: Use SMS Retriever API (no permissions)
      SmsRetrieverClient client = SmsRetriever.getClient(context);
      client.startSmsRetriever();
    • Bluetooth (API 31+):

      <!-- DON'T: Deprecated permissions -->
      <uses-permission android:name="android.permission.BLUETOOTH"/>
      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
      
      <!-- DO: Use new granular permissions -->
      <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
      <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
      <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
    • Contacts Access:

      // DON'T: Request full contacts access
      <uses-permission android:name="android.permission.READ_CONTACTS"/>
      
      // DO: Use Contacts Picker (user selects specific contacts)
      ActivityResultLauncher<Void> pickContact =
          registerForActivityResult(new PickContact(), uri -> {
              // Handle selected contact (no permission required)
          });
      pickContact.launch(null);
  3. Runtime Permission Requests

    For necessary permissions, request at runtime with clear justification:

    // Request permission only when needed with rationale
    if (ContextCompat.checkSelfPermission(this, CAMERA) != PERMISSION_GRANTED) {
        if (shouldShowRequestPermissionRationale(CAMERA)) {
            // Show explanation dialog
            showCameraRationaleDialog(() -> {
                requestPermissions(new String[]{CAMERA}, REQUEST_CAMERA);
            });
        } else {
            requestPermissions(new String[]{CAMERA}, REQUEST_CAMERA);
        }
    }

The following table shows alternative approaches by permission:

Permission Modern Alternative

READ_EXTERNAL_STORAGE

Photo Picker API, Scoped Storage (MediaStore), Storage Access Framework (SAF)

WRITE_EXTERNAL_STORAGE

Scoped Storage with MediaStore, getExternalFilesDir() for app-specific storage

READ_SMS / RECEIVE_SMS

SMS Retriever API (OTP), SMS User Consent API (user approves specific message)

ACCESS_FINE_LOCATION

ACCESS_COARSE_LOCATION (sufficient for most use cases like weather, timezone)

READ_CONTACTS

Contacts Picker API (user selects specific contacts, no permission needed)

CAMERA

Request at runtime only when camera feature is used, not upfront

BLUETOOTH / BLUETOOTH_ADMIN

BLUETOOTH_CONNECT, BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE (API 31+)

READ_PHONE_STATE

READ_PHONE_NUMBERS (API 31+) for specific access, or remove if not needed

Configuration

This detector provides configuration properties to customize permission lists for specific app contexts:

properties:
  # TIER 1: Critical permissions (malware indicators)
  criticalPermissions:
    - android.permission.BIND_ACCESSIBILITY_SERVICE
    - android.permission.SYSTEM_ALERT_WINDOW
    # Add custom critical permissions

  # TIER 2: Broad access permissions
  broadAccessPermissions:
    - android.permission.MANAGE_EXTERNAL_STORAGE
    # Add custom broad permissions

  # TIER 3: Deprecated permissions
  deprecatedPermissions:
    - android.permission.WRITE_EXTERNAL_STORAGE
    # Add custom deprecated permissions

  # TIER 4: Privacy-sensitive permissions
  privacySensitivePermissions:
    - android.permission.READ_SMS
    # Add custom privacy-sensitive permissions

References