Skip to content

Android Network Communication

Overview

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.

<application android:networkSecurityConfig="@xml/network_security_config"

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 ( Monitoring 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-config applies to all connections that the app attempts to make.
  • domain-config overrides base-config for specific domains (it can contain multiple domain entries).

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 localhost.

<?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>

Learn more:

Default Configurations

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>

Certificate Pinning

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>

Security Provider

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.