Mobile apps send credentials, session tokens and personal data over Wi-Fi, carrier networks and Bluetooth that the publisher does not control, and a single disabled certificate check is enough to hand that traffic to whoever sits in the middle. OWASP lists this as M5: Insecure Communication in the Mobile Top 10 2024. This guide goes beyond the overview to cover what M5 includes, the two MASVS network controls, the Android Network Security Configuration and iOS App Transport Security settings that decide most outcomes, and when certificate or public key pinning is worth its operational cost. It also covers rollout, testing, metrics and framework mapping. It is written for mobile developers, application security engineers and the platform teams who run the APIs and certificates behind an app. For the full list, see the OWASP Mobile Top 10 Guide.
Key takeaways
- The platform defaults are good; most findings switch them off. Android blocks cleartext for apps targeting API 28 and higher and ignores user-installed CAs from API 24, and iOS enforces App Transport Security. Custom trust managers, hostname verifiers and broad exceptions undo this.
- Certificate validation is mandatory, pinning is a choice. MASVS-NETWORK-1 requires secure traffic for every app; MASVS-NETWORK-2 asks for identity pinning only for endpoints the developer controls.
- Pin public keys, always with a backup. Pin the SubjectPublicKeyInfo (SPKI) hash, prefer a CA or intermediate key over a single leaf, and ship at least one backup pin plus a recovery path.
- Fail closed, never ask the user. A failed validation ends the connection. Overriding
onReceivedSslErrorto proceed, or offering a "continue anyway" button, recreates the vulnerability. - Every channel counts. OWASP's scope includes Bluetooth, NFC, SMS and push, not only HTTPS to your API, and says sensitive data must never travel by SMS, MMS or push notification.
What it is and who it applies to
OWASP's M5 page frames the threat as anyone who can observe traffic between the app and a server: an attacker on the same local network, such as a compromised or monitored Wi-Fi network, rogue carrier or network equipment (routers, cell towers, proxies), or malware on the device itself. OWASP rates exploitability as easy, prevalence as common, detectability as average, technical impact as severe and business impact as moderate.
The page names three recurring implementation flaws: outdated protocols or poor configuration, accepting invalid certificates (self-signed, revoked, expired or for the wrong host), and inconsistent encryption, for example protecting only the login flow. Its scope is any transfer between two endpoints: app to server, mobile to mobile, and device to local peer over TCP/IP, Wi-Fi, Bluetooth, NFC, audio, infrared, cellular and SMS. Two boundaries keep the risk distinct: data stored on the device belongs to M9, and strong transport with a weak session identifier belongs to M3. Scenarios on the page include an app that accepts any certificate, so a TLS proxy reads everything, and a session identifier sent over an insecure channel that lets an attacker bypass two-factor authentication.
M5 applies to every app that talks to a network. It weighs most on apps carrying credentials, payment or health data, apps used on public Wi-Fi, and apps whose backend tokens give access to other users' data.
Structure and key requirements
| MASVS control | Control statement | Scope |
|---|---|---|
| MASVS-NETWORK-1 | The app secures all network traffic according to the current best practices. | Every connection, including those made through low-level APIs and third-party libraries that can bypass platform defaults |
| MASVS-NETWORK-2 | The app performs identity pinning for all remote endpoints under the developer's control. | Trusting only specific CAs or keys for your own endpoints, rather than every root the device trusts |
OWASP's prevention list for M5, in practical form:
- Assume a hostile network: use TLS for every channel to a backend API or web service, and load third-party resources over HTTPS so mixed content does not leak session IDs.
- Validate fully: accept only certificates from trusted CAs, reject self-signed, expired, untrusted, revoked or wrong-host certificates, verify the full chain, and connect only after the server's identity is confirmed.
- Use strong suites: current cipher suites and key lengths. ASVS 5.0 V12.1.1 sets the server baseline of TLS 1.2 and TLS 1.3 only.
- Keep test shortcuts out of builds: use self-signed certificates or a local development CA in development rather than disabling checks.
- Keep secrets off side channels: no sensitive data over SMS, MMS or push; consider an application-level encryption layer as an additional defence for the most sensitive payloads.
Platform settings reference
| Setting | Platform | Secure use | Common mistake |
|---|---|---|---|
cleartextTrafficPermitted | Android Network Security Configuration | Off by default for API 28 and higher; enable only in a domain-config for a named legacy host | true in base-config |
<trust-anchors> | Android | System CAs only (user CAs are trusted by default only for apps targeting API 23 and lower) | <certificates src="user"/> in release, which lets any user-installed CA intercept |
<debug-overrides> | Android | Test CAs, applied only when android:debuggable is true | Test CAs placed in base-config |
<pin-set> | Android | SHA-256 SPKI pins with a backup pin; includeSubdomains scoped deliberately | No backup pin; an expiration date in the past, which silently disables pinning |
<certificateTransparency> | Android 16 and higher | Opt in on Android 16; on by default from Android 17 (API 37) | Expecting CT checks on connections that use custom trust anchors, where they are not performed |
X509TrustManager, HostnameVerifier | Android code | Use the platform defaults; if checkServerTrusted is extended, keep full validation | Empty checkServerTrusted, allow-all hostname verifier |
WebViewClient.onReceivedSslError | Android WebView | Leave the default, which cancels the load | Calling handler.proceed() |
NSAllowsArbitraryLoads | iOS App Transport Security | Absent or false; use a narrow NSExceptionDomains entry when a legacy host cannot be fixed | Set to true to make one HTTP endpoint work |
NSPinnedDomains | iOS | NSPinnedCAIdentities or NSPinnedLeafIdentities with SPKI-SHA256-BASE64 values and backups | Custom delegate code that skips default trust evaluation |
Certificate pinning decisions
Pinning narrows trust from every CA the device accepts to a set of keys you choose. It stops interception by a mis-issued certificate or a CA installed on the device, at the cost of outage risk whenever keys change. Apple states that pinning is not required and should be deployed with caution, and the OWASP Pinning Cheat Sheet advises against it when you do not control both client and server, cannot update the pin set securely, or cannot predict the key pair before it goes into service. MASVS-NETWORK-2 limits the requirement to endpoints under the developer's control, so third-party SDK and CDN endpoints are normally out of scope.
| Pin target | Strength | Operational risk | When to choose |
|---|---|---|---|
| Leaf SPKI | Highest: only your key is trusted | Any key rotation needs an app update unless a backup key is pinned | You control key generation and can pre-generate the next key |
| Intermediate or issuing CA SPKI | High: any certificate from that CA is trusted | Survives leaf renewals; breaks if the CA changes intermediate | Default for most apps; Apple recommends CA keys where possible |
| Root CA SPKI | Moderate: trusts all of the root's intermediates | Lowest | Rarely worth it; the cheat sheet does not recommend it |
| Whole certificate | High | Breaks on every renewal | Avoid, particularly with short certificate lifetimes |
| No pinning, strict validation plus CT | Relies on the CA system and CT logging | Lowest | Most apps without high-value endpoints, and all third-party endpoints |
Shorter certificate lifetimes increase the case for pinning keys rather than certificates and for automating rotation. See the Certificate Expiry Outages and 47-Day TLS Certificates Guide and the Certificate Transparency Guide.
Small vs large organisations: a small team with one app and a managed CDN certificate is usually better served by strict validation, no cleartext and CT than by pinning it cannot operate. A bank or health provider with its own API domains and a certificate team can pin intermediate keys with backups, owned by the team that rotates the certificates, with the pin set reviewed at every certificate change.
Identity and NHI requirements
The traffic M5 protects is mostly identity material: passwords, OAuth tokens, refresh tokens, one-time codes and API keys. OWASP's M5 impact statement names credentials, session tokens and two-factor codes as what an interceptor captures.
- Tokens are only as safe as the channel: a bearer token sent once over a weak channel can be replayed until it expires. Use short-lived access tokens, rotate refresh tokens, and consider sender-constrained tokens for high-value APIs. See the Token and Session Security Guide.
- Client certificates are non-human identities: where an app or managed device authenticates with mutual TLS, the private key belongs in the Android Keystore or iOS Keychain (hardware-backed where available), with issuance, rotation and revocation owned like any machine credential. See the mTLS Guide and the Machine Identity, PKI and Certificate Lifecycle Guide.
- Server keys behind your pins are credentials too: pinned TLS keys need named owners, a documented rotation plan and a backup key generated in advance, or a routine renewal becomes an outage.
- Embedded API keys travel with every request: intercepted traffic exposes any key the app sends. Keep privileged keys server-side, as covered in the OWASP Mobile Top 10 M1 Improper Credential Usage Guide.
Implementation steps
- Map every channel: list the hosts the app contacts (own APIs, SDKs, CDNs, WebView content), plus Bluetooth, NFC, local network and push flows. Capture traffic from a test build through an intercepting proxy to find hosts not in the documentation.
- Remove insecure code: search for custom
X509TrustManagerandHostnameVerifierimplementations,onReceivedSslErroroverrides, permissive OkHttp or networking library settings, and on iOS customURLSessionauthentication challenge handlers that accept any server trust. OWASP namessetAllowsAnyHTTPSCertificateas an example of code to remove. - Lock configuration: no cleartext in
base-config, system trust anchors only, test CAs only indebug-overrides; on iOS noNSAllowsArbitraryLoads, with any exception limited to a named domain and a ticket to remove it. - Fix the server side: TLS 1.2 and 1.3 only, forward-secret suites, publicly trusted certificates and HSTS on web endpoints, which the app inherits. Test with your usual TLS scanner. See the How TLS Works Guide.
- Decide on pinning: use the table above. If pinning, generate the backup key first, compute SPKI SHA-256 hashes for current and backup keys, and configure them declaratively (
<pin-set>,NSPinnedDomains) rather than in custom code, as the Pinning Cheat Sheet advises. - Test before release: confirm the app refuses a proxy with a user-installed CA, an expired certificate, a wrong-host certificate and a self-signed certificate, and that pinned endpoints refuse a valid certificate with an unpinned key. Repeat on the oldest supported OS version.
- Roll out in stages: ship pinning first to a staged rollout percentage, monitor connection failure rates by app version, and halt if failures rise. Keep a remote configuration flag that can steer clients to a degraded mode, as Apple suggests planning a fallback experience and recovery path.
- Run the rotation drill: before the primary key expires, switch the server to the backup key in a test environment and confirm released versions still connect. Then generate the next backup and ship it ahead of need.
Evidence and assessment
Assessors test MASVS-NETWORK-1 and NETWORK-2 using the MASTG methods (for example MASTG-TEST-0022, Testing Custom Certificate Stores and Certificate Pinning); the related weakness entry is MASWE-0028 Insecure Identity Pinning. Evidence to keep per release:
- Configuration files: the release
network_security_config.xmland the Info.plist ATS dictionary, reviewed and diffed against the previous release. - Interception test results: proxy runs showing which hosts accepted or refused interception, on Android and iOS.
- Static findings: scanner output for trust manager, hostname verifier and WebView SSL overrides.
- Pin register: pinned domains, key hashes, backup keys, owners and next rotation date.
For monitoring, watch backend TLS handshake failures by app version, client-side pin failure reports (log the failure without sending sensitive data), sessions presenting tokens from unexpected networks, and certificate expiry dates for pinned hosts. ASVS 5.0 V16.3.4 asks that security control failures such as backend TLS failures are logged.
| Metric | What good looks like |
|---|---|
| Release builds with cleartext permitted, user CAs trusted or arbitrary loads | Zero |
| Custom trust manager or SSL error overrides in release code | Zero |
| Hosts contacted by the app that pass interception testing | 100% refuse interception |
| Pinned domains with a backup key and named owner | 100% |
| Days of notice before a pinned key rotation | Greater than the time needed for most users to update |
| Pin failure rate per app version | Near zero; spikes investigated within a day |
Mapping to other frameworks
| Framework | Reference | Relevance to M5 |
|---|---|---|
| OWASP MASVS | MASVS-NETWORK-1, MASVS-NETWORK-2 | Testable requirements behind M5 |
| OWASP ASVS 5.0 (backend) | V12.1.1, V12.2.1, V12.3.2, V16.3.4 | TLS versions, TLS for all client connections with no insecure fallback, client certificate validation, logging TLS failures |
| NIST SP 800-53 Rev. 5 | SC-8, SC-8(1), SC-13, SC-17, SC-23, IA-5(2) | Transmission confidentiality and integrity, cryptographic protection, PKI certificates, session authenticity, public key-based authentication |
| NIST CSF 2.0 | PR.DS-02 | Data in transit protected |
| ISO/IEC 27001:2022 Annex A | A.5.14 Information transfer, A.8.20 Networks security, A.8.24 Use of cryptography | Policy and technical controls for data in transit |
| CIS Controls v8.1 | Safeguard 3.10 Encrypt Sensitive Data in Transit | Encryption of sensitive data in transit |
| MITRE ATT&CK | Mobile T1638 Adversary-in-the-Middle; Enterprise T1557 Adversary-in-the-Middle, T1040 Network Sniffing, T1689 Downgrade Attack | Interception and downgrade techniques M5 defends against |
| MITRE D3FEND and CAPEC | D3-CP Certificate Pinning, D3-CERO Certificate Rotation; CAPEC-94 Adversary in the Middle (AiTM) | Defensive techniques and the attack pattern |
Common pitfalls
- The staging trust manager that shipped: an allow-all trust manager written to reach a test server stays in a release build. Use
debug-overridesor a development CA instead, as OWASP advises. - One exception that became global:
NSAllowsArbitraryLoadsorcleartextTrafficPermitted="true"set app-wide for one legacy host, exposing every connection. - Pinning without a backup: the server certificate is renewed with a new key, every installed copy fails, and the emergency release removes pinning altogether.
- Pinning third-party hosts: pins on a CDN or SDK provider break when the provider rotates keys on its own schedule.
- TLS on login only: credentials are protected but later API calls or image loads carry the session ID in cleartext, the inconsistent encryption OWASP describes.
- Codes and links by SMS or push: sensitive data or reset links sent through channels OWASP says must not carry it, and which other apps or lock screens can read.
Practitioner checklist
- Keep an inventory of every host and local channel the app uses, refreshed from traffic captures each release.
- Fail the release build if cleartext is permitted globally, user CAs are trusted, or
NSAllowsArbitraryLoadsis true. - Remove custom trust managers, allow-all hostname verifiers and
onReceivedSslErroroverrides. - Require TLS 1.2 or 1.3 with forward-secret suites on every backend the app calls.
- Decide pinning per endpoint; pin SPKI hashes of CA or intermediate keys with at least one backup, declaratively.
- Assign owners and rotation dates to pinned keys and rehearse rotation before expiry.
- Test interception refusal on Android and iOS, including the oldest supported OS version.
- Keep credentials, codes and personal data off SMS, MMS and push.
- Store client certificates and tokens only in the Keystore or Keychain.
- Monitor TLS and pin failures by app version and alert on spikes.
Standards and references
- OWASP: Mobile Top 10 2024 M5 Insecure Communication
- OWASP: Mobile Application Security Verification Standard
- OWASP: Pinning Cheat Sheet
- OWASP: Application Security Verification Standard 5.0
- Android Developers: Network security configuration
- Apple Developer: Identity Pinning, how to configure server certificates for your app
- NIST: SP 800-53 Rev. 5
Related NHI Mgmt Group resources: OWASP Mobile Top 10 Guide · Mobile App Security Testing Guide · mTLS Guide · TLS Inspection Guide · OWASP Mobile Top 10 M4 Insufficient Input and Output Validation Guide