Implementation
const highRiskPermissions = [
// ---------------- SMS ----------------
PermissionInfo(
permission: 'android.permission.READ_SMS',
risk: PermissionRisk.high,
category: 'SMS',
reason: 'Accesses the user\'s private text messages.',
recommendation:
'Use SMS Retriever API or SMS User Consent API for OTP verification instead. '
'If a full messaging use case is required, app must be the default SMS/Assistant handler '
'and submit a Play Console Permissions Declaration.',
),
PermissionInfo(
permission: 'android.permission.SEND_SMS',
risk: PermissionRisk.high,
category: 'SMS',
reason: 'Can send SMS messages, including silently in the background.',
recommendation:
'Use Intent.ACTION_SENDTO to delegate sending to the default SMS app. '
'If silent sending is core to the app, requires default handler status + declaration.',
),
PermissionInfo(
permission: 'android.permission.RECEIVE_SMS',
risk: PermissionRisk.high,
category: 'SMS',
reason: 'Intercepts incoming SMS messages.',
recommendation:
'Use SMS Retriever API or SMS User Consent API for OTP flows (no permission needed). '
'Declaration + default handler status required for a full messaging app.',
),
PermissionInfo(
permission: 'android.permission.WRITE_SMS',
risk: PermissionRisk.high,
category: 'SMS',
reason: 'Modifies the SMS database.',
recommendation:
'Almost always removable — rarely a legitimate use case. '
'If truly needed, requires default handler status + declaration.',
),
PermissionInfo(
permission: 'android.permission.RECEIVE_MMS',
risk: PermissionRisk.high,
category: 'SMS',
reason: 'Intercepts incoming MMS messages.',
recommendation:
'No direct alternative. Requires default handler status + Play Console declaration.',
),
PermissionInfo(
permission: 'android.permission.RECEIVE_WAP_PUSH',
risk: PermissionRisk.high,
category: 'SMS',
reason: 'Intercepts WAP push messages.',
recommendation:
'Rarely needed today. Remove unless building a carrier/messaging app; otherwise requires declaration.',
),
// ---------------- Call Log / Telephony ----------------
PermissionInfo(
permission: 'android.permission.READ_CALL_LOG',
risk: PermissionRisk.high,
category: 'Call Log',
reason: 'Reads the user\'s call history.',
recommendation:
'Offer manual number entry as a fallback instead. '
'Must be default Phone/Assistant handler + declaration if retained.',
),
PermissionInfo(
permission: 'android.permission.WRITE_CALL_LOG',
risk: PermissionRisk.high,
category: 'Call Log',
reason: 'Modifies the user\'s call history.',
recommendation:
'Remove unless building a dialer/call-management app. Requires declaration if kept.',
),
PermissionInfo(
permission: 'android.permission.PROCESS_OUTGOING_CALLS',
risk: PermissionRisk.high,
category: 'Call Log',
reason:
'Can intercept and redirect outgoing calls. Deprecated on newer Android.',
recommendation:
'Migrate to CallRedirectionService (Android 10+). Otherwise requires declaration.',
),
PermissionInfo(
permission: 'android.permission.CALL_PHONE',
risk: PermissionRisk.high,
category: 'Telephony',
reason: 'Places phone calls without user interaction or confirmation.',
recommendation:
'Use Intent.ACTION_DIAL or Intent.ACTION_CALL via the dialer UI instead, '
'unless silent/auto-dialing is the core feature (then declaration required).',
),
PermissionInfo(
permission: 'android.permission.ANSWER_PHONE_CALLS',
risk: PermissionRisk.high,
category: 'Telephony',
reason: 'Programmatically answers incoming calls.',
recommendation:
'Remove unless building a call-screening/call-management app. Requires declaration.',
),
// ---------------- Location ----------------
PermissionInfo(
permission: 'android.permission.ACCESS_BACKGROUND_LOCATION',
risk: PermissionRisk.high,
category: 'Location',
reason:
'Tracks the user\'s location even when the app is closed or not in use.',
recommendation:
'Use foreground-only location (ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION) unless a core, '
'user-beneficial background feature exists. Requires a Play Console declaration + demo video.',
),
// ---------------- Storage / Files ----------------
PermissionInfo(
permission: 'android.permission.MANAGE_EXTERNAL_STORAGE',
risk: PermissionRisk.high,
category: 'Storage',
reason:
'Grants broad, unrestricted access to shared storage ("All files access").',
recommendation:
'Use the Storage Access Framework or MediaStore API instead. '
'Only keep for genuine file-manager/backup apps — requires declaration.',
),
// ---------------- Package Visibility ----------------
PermissionInfo(
permission: 'android.permission.QUERY_ALL_PACKAGES',
risk: PermissionRisk.high,
category: 'Package Visibility',
reason: 'Reveals the full list of installed apps on the device.',
recommendation:
'Declare specific packages/intents using a scoped <queries> block instead. '
'Only keep broad access for launcher/antivirus-type apps — requires declaration.',
),
// ---------------- Accessibility ----------------
PermissionInfo(
permission: 'android.permission.BIND_ACCESSIBILITY_SERVICE',
risk: PermissionRisk.high,
category: 'Accessibility',
reason:
'Grants full read/control access to the device UI. Frequently abused for financial fraud malware.',
recommendation:
'If a genuine accessibility tool, set isAccessibilityTool=true. Otherwise requires '
'clear in-app disclosure, explicit user consent, and a Play Console declaration.',
),
// ---------------- Overlay ----------------
PermissionInfo(
permission: 'android.permission.SYSTEM_ALERT_WINDOW',
risk: PermissionRisk.high,
category: 'Special Access',
reason: 'Allows drawing over other apps (overlay UI).',
recommendation:
'Prefer in-app UI over system overlays where possible. If required, '
'direct users to the system settings page for approval (special permission, not runtime-granted).',
),
// ---------------- Device Admin ----------------
PermissionInfo(
permission: 'android.permission.BIND_DEVICE_ADMIN',
risk: PermissionRisk.high,
category: 'Device Admin',
reason:
'Grants device admin control — device wipe, lock, and policy enforcement.',
recommendation:
'Remove unless building an enterprise MDM/device-management app.',
),
// ---------------- Notifications ----------------
PermissionInfo(
permission: 'android.permission.BIND_NOTIFICATION_LISTENER_SERVICE',
risk: PermissionRisk.high,
category: 'Notifications',
reason:
'Reads all notifications posted by every app on the device. Frequently abused for fraud.',
recommendation:
'No real alternative exists. Requires a Play Console declaration with a strong core-functionality justification.',
),
// ---------------- Install Packages ----------------
PermissionInfo(
permission: 'android.permission.REQUEST_INSTALL_PACKAGES',
risk: PermissionRisk.high,
category: 'Package Install',
reason: 'Allows the app to trigger installation of other APK packages.',
recommendation:
'Use a Play Store deep link for updates/installs instead. '
'Keep only for browser/file-manager/enterprise apps — requires declaration.',
),
// ---------------- Body Sensors ----------------
PermissionInfo(
permission: 'android.permission.BODY_SENSORS',
risk: PermissionRisk.high,
category: 'Health',
reason:
'Accesses body sensor data such as heart rate, SpO2, and skin temperature.',
recommendation:
'On Android 16+, migrate to granular permissions (e.g., android.permission.health.READ_HEART_RATE). '
'Declaration required regardless of which variant is used.',
),
PermissionInfo(
permission: 'android.permission.BODY_SENSORS_BACKGROUND',
risk: PermissionRisk.high,
category: 'Health',
reason: 'Accesses body sensor data while the app is in the background.',
recommendation:
'Only request if background monitoring is core to the app (e.g., workout tracking). '
'Requires declaration; prefer granular health.* permissions on Android 16+.',
),
// ---------------- VPN ----------------
PermissionInfo(
permission: 'android.permission.BIND_VPN_SERVICE',
risk: PermissionRisk.high,
category: 'Network',
reason:
'Creates a device-level VPN tunnel with visibility into all network traffic.',
recommendation:
'Only keep for genuine VPN, parental-control, or device-security apps. '
'Must encrypt device-to-tunnel traffic and be declared in the Play listing.',
),
// ---------------- Accounts ----------------
PermissionInfo(
permission: 'android.permission.GET_ACCOUNTS',
risk: PermissionRisk.high,
category: 'Accounts',
reason: 'Lists all accounts (e.g., emails) registered on the device.',
recommendation:
'Use Google Sign-In / OAuth-based sign-in flows instead. Usually fully removable.',
),
];