Android Network Communication¶
Almost every Android app acts as a client to one or more remote services. As this network communication usually takes place over untrusted networks such as public Wi-Fi, classical network based-attacks become a potential issue.
Most modern mobile apps use variants of HTTP-based web services, as these protocols are well-documented and supported.
Android Network Security Configuration¶
Starting on Android 7.0 (API level 24), Android apps can customize their network security settings using the so-called Network Security Configuration feature which offers the following key capabilities:
- Cleartext traffic: Protect apps from accidental usage of cleartext traffic (or enables it).
- Custom trust anchors: Customize which Certificate Authorities (CAs) are trusted for an app's secure connections. For example, trusting particular self-signed certificates or restricting the set of public CAs that the app trusts.
- Certificate pinning: Restrict an app's secure connection to particular certificates.
- Debug-only overrides: Safely debug secure connections in an app without added risk to the installed base.
If an app defines a custom Network Security Configuration, you can obtain its location by searching for
android:networkSecurityConfig in the AndroidManifest.xml file.
In this case the file is located at
@xml (equivalent to /res/xml) and has the name "network_security_config" (which might vary). You should be able to find it as "res/xml/network_security_config.xml". If a configuration exists, the following event should be visible in the system logs:
D/NetworkSecurityConfig: Using Network Security Config from resource network_security_config
The Network Security Configuration is XML-based and can be used to configure app-wide and domain-specific settings:
base-configapplies to all connections that the app attempts to make.
base-configfor specific domains (it can contain multiple
For example, the following configuration uses the
base-config to prevent cleartext traffic for all domains. But it overrides that rule using a
domain-config, explicitly allowing cleartext traffic for
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="false" /> <domain-config cleartextTrafficPermitted="true"> <domain>localhost</domain> </domain-config> </network-security-config>
- "A Security Analyst’s Guide to Network Security Configuration in Android P"
- Android Developers - Network Security Configuration
- Android Codelab - Network Security Configuration
The default configuration for apps targeting Android 9 (API level 28) and higher is as follows:
<base-config cleartextTrafficPermitted="false"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
The default configuration for apps targeting Android 7.0 (API level 24) to Android 8.1 (API level 27) is as follows:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
The default configuration for apps targeting Android 6.0 (API level 23) and lower is as follows:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config>
The Network Security Configuration can also be used to pin declarative certificates to specific domains. This is done by providing a
<pin-set> in the Network Security Configuration, which is a set of digests (hashes) of the public key (
SubjectPublicKeyInfo) of the corresponding X.509 certificate.
When attempting to establish a connection to a remote endpoint, the system will:
- Get and validate the incoming certificate.
- Extract the public key.
- Calculate a digest over the extracted public key.
- Compare the digest with the set of local pins.
If at least one of the pinned digests matches, the certificate chain will be considered valid and the connection will proceed.
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> Use certificate pinning for OWASP website access including sub domains <domain includeSubdomains="true">owasp.org</domain> <pin-set expiration="2018/8/10"> <!-- Hash of the public key (SubjectPublicKeyInfo of the X.509 certificate) of the Intermediate CA of the OWASP website server certificate --> <pin digest="SHA-256">YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=</pin> <!-- Hash of the public key (SubjectPublicKeyInfo of the X.509 certificate) of the Root CA of the OWASP website server certificate --> <pin digest="SHA-256">Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys=</pin> </pin-set> </domain-config> </network-security-config>
Android relies on a security provider to provide SSL/TLS-based connections. The problem with this kind of security provider (one example is OpenSSL), which comes with the device, is that it often has bugs and/or vulnerabilities.
To avoid known vulnerabilities, developers need to make sure that the application will install a proper security provider. Since July 11, 2016, Google has been rejecting Play Store application submissions (both new applications and updates) that use vulnerable versions of OpenSSL.