Permissions are justified and minimized
Why it matters
App stores actively audit permission declarations for proportionality — a notes app requesting ACCESS_FINE_LOCATION or NSCameraUsageDescription without a plausible justification triggers manual review and frequently results in rejection or removal. Under GDPR Art. 5(1)(c) (data minimisation) and CWE-272 (least privilege violation), requesting permissions beyond what your app's core function requires constitutes a legal compliance failure, not just a policy violation. Apple's privacy nutrition label (apple-privacy-permission-usage) surfaces every declared permission to users before install; overly broad permission sets reduce install conversion and increase uninstalls. iOS rejects binaries that declare a permission in Info.plist without a corresponding NS*UsageDescription string — this is an automated binary validation failure.
Severity rationale
Medium because missing `NS*UsageDescription` strings trigger automated iOS binary rejection, and overly broad permission sets expose the app to GDPR Art. 5(1)(c) violations and store reviewer scrutiny.
Remediation
Audit app.json for every declared permission and add a precise usage description for iOS. Remove any permissions your app does not actually invoke at runtime.
// app.json
{
"expo": {
"ios": {
"infoPlist": {
"NSCameraUsageDescription": "Used to scan QR codes for event check-in.",
"NSPhotoLibraryUsageDescription": "Used to attach photos to your reports."
}
},
"android": {
"permissions": [
"android.permission.CAMERA"
]
}
}
}
For each permission, verify with a code search that it is actually called (Camera.requestCameraPermissionsAsync(), etc.) — remove any that aren't. Cross-reference with the App Store Privacy & Data audit (app-store-privacy-data) for the full ATT and data collection declaration requirements.
Detection
- ID:
permissions-justified - Severity:
medium - What to look for: Check
app.jsonforios.infoPlistwith privacy permissions (NSCameraUsageDescription, NSPhotoLibraryUsageDescription, NSLocationWhenInUseUsageDescription, etc.) andandroid.permissionsarray. Each permission listed should have a clear justification in the app's privacy policy or usage description. Look for excessive permissions (e.g., requesting WRITE_EXTERNAL_STORAGE if not needed, or tracking location when not required). - Pass criteria: Count all declared permissions across both platforms. Each permission has a matching privacy description in iOS (at least 10 characters explaining usage) and a justification for Android. No more than 0 permissions should lack a corresponding usage description. Permissions list is minimal (only requested permissions actually used by the app).
- Fail criteria: Missing privacy descriptions for iOS permissions, permissions that appear unnecessary (e.g., location permission in a note-taking app), or overly broad permission set without justification.
- Skip (N/A) when: App uses no special permissions (basic camera, microphone, location not required).
- Cross-reference: The App Store Privacy & Data audit (
app-store-privacy-data) provides a deeper analysis of privacy declarations and App Tracking Transparency compliance. - Detail on fail:
"Camera permission requested but no usage description (NSCameraUsageDescription) in Info.plist"or"App requests both READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE but only displays images (read-only)" - Remediation: App stores scrutinize permission requests. Justify and minimize permissions:
- For iOS, add to app.json:
"ios": { "infoPlist": { "NSCameraUsageDescription": "We use your camera to capture photos for...", "NSPhotoLibraryUsageDescription": "We need access to your photo library to...", "NSLocationWhenInUseUsageDescription": "We use your location to find nearby..." } } - For Android, in app.json or AndroidManifest.xml:
"android": { "permissions": ["android.permission.CAMERA", "android.permission.ACCESS_FINE_LOCATION"] } - Only request permissions your app actually uses
- Request permissions at runtime (not just manifest declaration)
- Explain why each permission is needed in your app's privacy policy
- For iOS, add to app.json:
External references
- cwe · CWE-272 — Least Privilege Violation
- gdpr · Art. 5(1)(c) — GDPR — Data minimisation principle
- external · apple-privacy-permission-usage — Apple Developer — Requesting access to protected resources
- external · android-permissions-overview — Android Developer — Permissions on Android
Taxons
History
- 2026-04-18·v1.0.0·Initial import from mobile-store-readiness·automated