Most mobile security misconfigurations are a single attribute in a manifest or property list that nobody reviewed before release. M8 Security Misconfiguration is the eighth risk in the OWASP Mobile Top 10 2024, and it covers the settings, permissions and platform declarations that leave an otherwise sound app exposed: debuggable builds, exported components, open file providers, permissive backup, cleartext exceptions and excessive permissions. This guide goes deeper than the overview in the OWASP Mobile Top 10 Guide. It lists the exact Android and iOS settings to check, how to enforce them in the build pipeline, how to gather evidence for an assessment, and where M8 maps to MASVS, NIST and ISO controls. It is written for mobile developers, AppSec engineers and penetration testers who own release quality for Android and iOS apps.
Key takeaways
- M8 is easy to find and easy to fix. OWASP rates its detectability EASY and prevalence COMMON: the settings sit in AndroidManifest.xml, the Network Security Configuration and Info.plist, so a policy check in CI catches most of them before release.
- Explicit beats default. Android defaults have changed across API levels (cleartext traffic, exported components, backup), so set every security-relevant attribute explicitly rather than inheriting whatever the target SDK implies.
- Exported components are the largest attack surface. An activity, service, receiver or provider exported by accident lets any installed app call internal functionality; OWASP lists exported activities and file provider root paths as named scenarios.
- Backup and debug settings leak data and credentials. Auto Backup copies shared preferences, databases and files by default, and a debuggable release build lets anyone with a cable inspect memory and storage.
- The backend counts too. Mobile apps ship configuration that points at cloud buckets and Firebase projects; when those backends allow unauthenticated access, the app configuration becomes a public map to the data.
What it is and who it applies to
OWASP defines M8 as "the improper configuration of security settings, permissions, and controls that can lead to vulnerabilities and unauthorized access". The official risk name on the OWASP Mobile Top 10 2024 list is M8: Security Misconfiguration, which matches this guide's title. OWASP rates exploitability DIFFICULT, prevalence COMMON, detectability EASY and both technical and business impact SEVERE. The threat agents it names are an attacker with physical access to the device and a malicious app on the same device that abuses the misconfiguration to act in the vulnerable app's context.
The risk applies to every native, hybrid and cross-platform app (React Native, Flutter, Xamarin and .NET MAUI all compile down to the same manifest and Info.plist), and to the configuration of the services the app talks to. It overlaps with neighbouring risks, and the boundaries are worth fixing early so findings are not double counted:
- M5 Insecure Communication: cleartext and pinning settings are configuration (M8), while TLS validation logic in code is M5. See the OWASP Mobile Top 10 M5 Insecure Communication Guide.
- M9 Insecure Data Storage: world-readable files and backup flags are configuration; what the app writes and where is M9. See the OWASP Mobile Top 10 M9 Insecure Data Storage Guide.
- M7 Insufficient Binary Protections: debuggable flags are M8; obfuscation and anti-tampering are M7.
- Server side: API and cloud misconfiguration is covered by the OWASP API Top 10 API8 Security Misconfiguration Guide, but mobile teams own the configuration their app depends on.
Structure and key requirements
OWASP's M8 page groups the risk into attack vectors (insecure defaults, improper access controls, weak cryptography, missing secure communication, unprotected storage, insecure file permissions, misconfigured session management) and prevention measures. The table below turns the prevention list into the concrete settings that implement each one, with the MASVS v2 control it supports.
| OWASP M8 prevention measure | Android setting to check | iOS setting to check | MASVS control |
|---|---|---|---|
| Disable debugging in production | android:debuggable absent or false in release; no WebView.setWebContentsDebuggingEnabled(true) in release code | Release build signed with a distribution profile, so the get-task-allow entitlement is false | MASVS-RESILIENCE-4, MASVS-CODE-4 (supporting) |
| Secure network configuration | Network Security Config: no cleartextTrafficPermitted="true" in base-config; no <certificates src="user"/> outside debug-overrides; pin-set with a backup pin | App Transport Security: no NSAllowsArbitraryLoads; narrow NSExceptionDomains entries only | MASVS-NETWORK-1, MASVS-NETWORK-2 |
| Disable or restrict backup | android:allowBackup set explicitly; dataExtractionRules (API 31+) and fullBackupContent (API 30 and lower) excluding secrets | Sensitive files flagged as excluded from backup; keychain items use a ThisDeviceOnly accessibility class | MASVS-STORAGE-2 |
| Limit exported attack surface | android:exported set explicitly on every component; signature-level permissions on components that must be exported | Custom URL schemes and universal links validated; app extensions reviewed | MASVS-PLATFORM-1 |
| Safe file provider paths | FileProvider with exported="false", grantUriPermissions="true", no <root-path>, narrow files-path entries | Shared App Group containers hold no secrets | MASVS-PLATFORM-1, MASVS-STORAGE-1 |
| No world-readable or world-writable files | No MODE_WORLD_READABLE or MODE_WORLD_WRITEABLE; no sensitive data in shared external storage | No sensitive files written outside the app container | MASVS-STORAGE-1 |
| Least privilege permissions | Only required <uses-permission> entries; review merged manifest for permissions added by SDKs | Only required usage description keys (NS...UsageDescription) and entitlements | MASVS-PRIVACY-1 |
| No hardcoded default credentials | No test accounts, admin passwords or API keys in resources or BuildConfig | No credentials in Info.plist, xcconfig or bundled JSON | MASVS-STORAGE-1 (see M1 for credentials) |
Android defaults that changed
Android's official documentation shows why relying on defaults is fragile. android:usesCleartextTraffic defaults to true for apps targeting API 27 or lower and false for apps targeting API 28 or higher, and it is ignored on Android 7.0 (API 24) and later when a Network Security Configuration is present. The Network Security Configuration's default base-config for apps targeting API 24 and higher trusts only system certificate authorities, so user-installed CAs are trusted only if the app opts in. android:allowBackup defaults to true, and on Android 12 (API 31) and later some manufacturers' devices still allow device-to-device transfer even when it is false. Android's guidance on android:exported notes that its default has varied by component type and version (providers defaulted to exported on API 16 and lower) and tells developers to always set it explicitly. Since Android 12, components that declare an intent filter must declare android:exported or the app will not install.
Network Security Configuration details that matter
- Pins:
pin-setentries are SHA-256 digests of the certificate's SubjectPublicKeyInfo. Android's documentation says to always include a backup pin so keys or CAs can be rotated without an app update. - Pin expiry: the optional
expirationattribute disables pinning after the date. It prevents lock-out in apps that never update, but a date in the past silently turns pinning off. - Debug trust: trust anchors inside
debug-overridesapply only whenandroid:debuggable="true", which is safer than conditional code because app stores reject debuggable builds. - overridePins: setting it to true on a trust anchor skips pinning for chains from that source; it should not appear in release configuration outside
debug-overrides.
Identity and NHI requirements
Several M8 findings are identity findings in disguise, because the setting that is wrong exposes a credential or lets a caller skip authentication.
- Exported components that skip login: an exported activity that opens an account screen, or a service that performs an action, bypasses the app's own authentication flow. Treat every exported component as an unauthenticated API endpoint and protect it with a signature-level permission or by not exporting it. See the OWASP Mobile Top 10 M3 Insecure Authentication and Authorization Guide.
- Backup that carries sessions: refresh tokens and device-bound keys restored to another device become a cloned session. Exclude token stores from
cloud-backupanddevice-transfer, and store keys in the Android Keystore or aThisDeviceOnlykeychain class so a restored copy is unusable. - Configuration that ships machine credentials: API keys, cloud bucket names and Firebase project identifiers in resources are non-human identities that the app presents to backends. They must be restricted on the server side (key restrictions, security rules, App Check style attestation) because anything in the package can be extracted. See the OWASP Mobile Top 10 M1 Improper Credential Usage Guide and the Firebase Credentials Security Guide.
- Backend rules as access control: Firebase's own documentation labels
allow read, write: if true;"Not recommended" and warns that rules checking onlyauth != nulllet any signed-in user read the data. Owner-based rules such as comparingrequest.auth.uidto an owner field are the minimum for per-user data. - Signing and distribution identities: the signing key and the provisioning profile decide whether a build is debuggable and which keychain access groups it can read. Keep signing keys in a managed store with named owners, not on developer laptops.
Cybernews' study of 156,080 iOS apps, summarised in our iOS Apps Leaking Hard-Coded Secrets 2025 breach page, found 836 of 94,240 hard-coded storage bucket instances accepted requests without authentication and 2,218 Firebase instances had misconfigured authentication. The app configuration pointed straight at backends that were themselves misconfigured.
Implementation steps
- Inventory the configuration surface. For each app, collect the merged AndroidManifest.xml (after SDK manifests are merged), the Network Security Configuration, backup rules XML, FileProvider paths XML, Info.plist, entitlements and the list of backend projects (Firebase, buckets, API gateways) the app uses. The merged manifest matters: third-party SDKs add permissions and components you never wrote.
- Write a release baseline. Turn the table above into a short, versioned baseline per platform: required values, forbidden values and approved exceptions with an owner and expiry date. Store it next to the code so changes are reviewed.
- Enforce in CI in report-only mode first. Add a static check on the release variant (Android Lint rules, a MobSF or similar scan, or a simple XML and plist policy script) that reports violations without failing the build. Run it for two or three release cycles to find legitimate exceptions.
- Fix the high-value findings. Start with debuggable release builds, exported components without permissions,
root-pathproviders, global cleartext andNSAllowsArbitraryLoads, and backup of token stores. These are the ones OWASP names in its scenarios. - Switch the check to blocking. Once the exception list is stable, fail release builds on any violation not in the approved list. Keep debug and internal variants on report-only so developer workflows are not broken.
- Pilot with a staged rollout. Ship hardened builds through internal testing, then a staged production rollout (Google Play staged rollout, TestFlight then phased release on the App Store). Watch crash rates and support tickets for broken deep links, share flows and backup restores.
- Roll back safely. Configuration changes ride on app releases, so rollback means halting the staged rollout and shipping the previous build or a hotfix. For pinning, keep a backup pin and a server-side kill switch for the feature that depends on it, rather than relying on pin expiry.
- Review backends on the same cadence. Check Firebase rules, bucket policies and API key restrictions each release, using the platform's rules simulator or policy checks, and link the result to the app release record.
Evidence and assessment
OWASP says the way to establish whether an app is vulnerable is "a thorough security assessment, including code review, security testing, and configuration analysis". In practice M8 evidence is cheap to collect and should be attached to each release.
| Check | How to test | Evidence to keep |
|---|---|---|
| Release build not debuggable | Inspect the merged manifest of the signed APK or AAB; for iOS, inspect embedded entitlements of the distributed IPA | Manifest or entitlements extract per release |
| No unintended exported components | List all components with exported="true" or intent filters; call each from a test app on a test device and confirm permission enforcement | Component inventory with owner and justification |
| FileProvider paths narrow | Review the paths XML; attempt to request a URI outside the shared directory from a test app | Paths file diff and test result |
| Backup excludes secrets | Run backup and restore on a test device using the Android backup testing tools; check what the restored app contains | Backup rules XML and restore test notes |
| Cleartext and trust settings | Review Network Security Configuration and ATS keys; proxy traffic on a test device with a user CA installed and confirm the release build refuses it | Proxy test screenshot or log |
| Permissions minimal | Compare requested permissions and usage descriptions to the feature list | Permission register with business reason |
| Backend rules | Run unauthenticated and cross-user requests against each backend referenced in the app | Rules version and test output |
Metrics that show the control is working:
- Percentage of release builds that passed the configuration policy check without a waiver (target 100%).
- Number of exported components per app, and the share protected by a signature-level permission.
- Number of open configuration exceptions (cleartext domains, ATS exceptions, backup inclusions) and the share past their expiry date.
- Mean time from a configuration finding in CI or a pen test to a fixed release.
- Number of backend projects referenced by the app with rules or bucket policies reviewed in the last release cycle.
Assessors following MASVS will look for the controls in the mapping below; the Mobile App Security Testing Guide covers the test tooling and how to scope a MASVS assessment.
Mapping to other frameworks
| Framework | Reference | Relevance to M8 |
|---|---|---|
| OWASP MASVS v2 | MASVS-PLATFORM-1 "The app uses IPC mechanisms securely." | Exported components, providers, intents |
| OWASP MASVS v2 | MASVS-NETWORK-1 and MASVS-NETWORK-2 | Cleartext, trust anchors, identity pinning |
| OWASP MASVS v2 | MASVS-STORAGE-2 "The app prevents leakage of sensitive data." | Backup, world-readable files |
| OWASP MASVS v2 | MASVS-CODE-1 and MASVS-CODE-3 | Minimum platform version, components without known vulnerabilities |
| OWASP MASVS v2 | MASVS-PRIVACY-1 "The app minimizes access to sensitive data and resources." | Excessive permissions |
| NIST SP 800-53 Rev. 5 | CM-2 Baseline Configuration, CM-6 Configuration Settings, CM-7 Least Functionality | Release baseline, required settings, removing unneeded exported functionality |
| NIST SP 800-53 Rev. 5 | SA-11 Developer Testing and Evaluation, SC-8 Transmission Confidentiality and Integrity | CI policy checks; cleartext prohibition |
| NIST CSF 2.0 | PR.PS-01 Configuration management practices are established and applied; PR.PS-06 secure software development practices | Baseline and pipeline enforcement |
| ISO/IEC 27001:2022 Annex A | A.8.9 Configuration management; A.8.25 Secure development life cycle | Documented secure configuration and release gates |
| CIS Controls v8.1 | Safeguard 4.1 Establish and Maintain a Secure Configuration Process; 16.7 Use Standard Hardening Configuration Templates for Application Infrastructure | Baseline per platform and for backends |
| MITRE ATT&CK Mobile | T1409 Stored Application Data; T1638 Adversary-in-the-Middle | What an attacker gains from open providers, backups and cleartext exceptions |
Common pitfalls
- Checking the source manifest instead of the merged one: SDKs add components, permissions and providers during manifest merging. A clean
src/main/AndroidManifest.xmlsays little about what ships. Scan the built artefact. - Debug-only settings leaking into release: user CA trust, cleartext domains for a local test server or a WebView debugging call wrapped in a build flag that someone flipped. Keep debug trust in
debug-overridesand debug code in a separate source set so it cannot compile into release. - Exporting to make a deep link work: teams export a whole activity to support one link and forget the activity also accepts extras that change behaviour. Export a thin routing activity that validates input, and keep the rest internal.
- Broad FileProvider paths:
<root-path>or apath="."entry shared for convenience. Android's guidance is explicit: do not useroot-path, share narrow directories and grant onlyFLAG_GRANT_READ_URI_PERMISSIONwhen read access is enough. - Global ATS or cleartext opt-outs left from a migration: a single
NSAllowsArbitraryLoadsor base-config cleartext flag added for one legacy host disables protection for every connection. Use per-domain exceptions with an owner and a removal date. - Assuming the backend is someone else's problem: the iOS app study above found open buckets and misconfigured Firebase projects referenced directly from shipped apps. The Firebase Misconfigurations 2024 breach page shows the same rule failure at scale on the web side. See the Cloud Misconfiguration Guide.
Practitioner checklist
- Set
android:exported,android:allowBackupandandroid:networkSecurityConfigexplicitly in every Android app, whatever the target SDK. - Fail release builds that are debuggable, carry
get-task-allow, or enable WebView debugging. - Protect every exported component with a signature-level permission or remove the export; keep an inventory with owners.
- Restrict FileProvider paths to named subdirectories, never
root-path, and grant read-only URIs where possible. - Exclude token stores, databases with personal data and key material from
cloud-backupanddevice-transfer; test restore on a second device. - Remove global cleartext and
NSAllowsArbitraryLoads; allow per-domain exceptions only with an owner and expiry. - Pin backend identities with a backup pin and a tested rotation plan.
- Review the merged manifest permissions and iOS usage descriptions against the feature list every release.
- Test every backend the app references for unauthenticated and cross-user access each release.
- Track the five metrics above and review them at release readiness.
Standards and references
- OWASP: Mobile Top 10 2024, M8 Security Misconfiguration
- OWASP: Mobile Application Security Verification Standard
- Android Developers: application element reference
- Android Developers: Network security configuration
- Android Developers: android:exported risk
- Android Developers: Improperly exposed directories to FileProvider
- Android Developers: Back up user data with Auto Backup
- Firebase: Avoid insecure rules
Related NHI Mgmt Group resources: OWASP Mobile Top 10 Guide · Android App Security Guide · iOS App Security Guide · OWASP Mobile Top 10 M7 Insufficient Binary Protections Guide · OWASP Mobile Top 10 M10 Insufficient Cryptography Guide