From 06aabf4eb82823cd2d7035c179fd96bfa53f07e1 Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Mon, 22 Feb 2016 10:40:05 -0800 Subject: [PATCH] Add Network Security Config documentation. Initial pass at Network Security Config documentation, this also adds a Security section to the list of topics which is currently just a stub. Bug: 26931435 Change-Id: Iae0ec98a202ad3222b8f3ef39df77ecd2316504a --- docs/html/guide/guide_toc.cs | 10 + docs/html/guide/topics/security/index.jd | 7 + .../guide/topics/security/security-config.jd | 539 ++++++++++++++++++ 3 files changed, 556 insertions(+) create mode 100644 docs/html/guide/topics/security/index.jd create mode 100644 docs/html/guide/topics/security/security-config.jd diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index f3f2e5e7e780e..e99c15a14e6f8 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -631,6 +631,16 @@ + diff --git a/docs/html/guide/topics/security/index.jd b/docs/html/guide/topics/security/index.jd new file mode 100644 index 0000000000000..22fb775c47f8f --- /dev/null +++ b/docs/html/guide/topics/security/index.jd @@ -0,0 +1,7 @@ +page.title=Security +page.landing=true +page.landing.intro=Configure the security of your application. + +@jd:body +
+
diff --git a/docs/html/guide/topics/security/security-config.jd b/docs/html/guide/topics/security/security-config.jd new file mode 100644 index 0000000000000..4cee2536b904e --- /dev/null +++ b/docs/html/guide/topics/security/security-config.jd @@ -0,0 +1,539 @@ +page.title=Network Security Config +@jd:body + +
+ +
+ +

The Android Network Security Config lets apps customize their network security settings +in a safe, declarative configuration file without modifying application code. +These settings can be configured for specific domains and app-wide.

+ +

Features

+ + +

Examples

+

Trusting Custom CAs

+

An application may want to trust a custom set of CAs instead of the platform +default. The most common reasons of this are: +

+

+

By default secure (e.g. TLS, HTTPS) connections from all applications trust the pre-installed system CAs, and +applications targeting API level 23 (Android M) and below also trust the user-added CA store by default. +An application can customize its own connections using {@code base-config} (for app-wide customization) or +{@code domain-config} (for per-domain customization).

+ +

Trusting a Custom CA

+

Assume you want to connect to your host which uses a self-signed SSL certificate or to +a host whose SSL certificate is issued by a non-public CA which you trust, e.g., your company's internal +CA.

+

+res/xml/network_security_config.xml: +

+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <domain-config>
+        <domain includeSubdomains="true">example.com</domain>
+        <trust-anchors>
+            <certificates src="@raw/my_ca"/>
+        </trust-anchors>
+    </domain-config>
+</network-security-config>
+
+

+

Add the self-signed or non-public CA certificate, in PEM or DER format, to {@code res/raw/my_ca}.

+

+In AndroidManifest.xml reference the above config +

+<?xml version="1.0" encoding="utf-8"?>
+...
+<application ...>
+    <meta-data android:name="android.security.net.config"
+               android:resource="@xml/network_security_config" />
+    ...
+
+

+

Limiting the Set of Trusted CAs

+

An application that does not want to trust all CAs trusted by system can instead specify its own +reduced set of CAs to trust. This protects the application from fradulent certificates issued by any +of the other CAs.

+ +

The config to limit the set of trusted CAs is similar to trusting a custom CA +for a specific domain except that multiple CAs are provided in the resource.

+ +

+res/xml/network_security_config.xml: +

+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <domain-config>
+        <domain includeSubdomains="true">secure.example.com</domain>
+        <domain includeSubdomains="true">cdn.example.com</domain>
+        <trust-anchors>
+            <certificates src="@raw/trusted_roots"/>
+        </trust-anchors>
+    </domain-config>
+</network-security-config>
+
+

+

Add the trusted CAs, in PEM or DER format, to {@code res/raw/trusted_roots}. +Note that if using PEM format the file must contain only PEM data and no extra text. +You can also provide multiple <certificates> elements instead +of one.

+

+In AndroidManifest.xml reference the above config +

+<?xml version="1.0" encoding="utf-8"?>
+...
+<application ...>
+    <meta-data android:name="android.security.net.config"
+               android:resource="@xml/network_security_config" />
+    ...
+
+

+ +

Trusting Additional CAs

+

An application may want to trust additional CAs not trusted by the system, this could be due to +the system not yet including the CA or a CA that does not meet the requirements for inclusion into +the Android system. An application can do this by specifying multiple certificate sources for a configuration. +

+

+res/xml/network_security_config.xml: +

+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <base-config>
+        <trust-anchors>
+            <certificates src="@raw/extracas"/>
+            <certificates src="system"/>
+        </trust-anchors>
+    </base-config>
+</network-security-config>
+
+

+

+In AndroidManifest.xml reference the above config +

+<?xml version="1.0" encoding="utf-8"?>
+...
+<application ...>
+    <meta-data android:name="android.security.net.config"
+               android:resource="@xml/network_security_config" />
+    ...
+
+

+ +

Debugging-only CAs

+

When debugging an application that connects over HTTPS you may want to connect to a local development +server, which does not have the SSL certificate for your production server. In order to support this +without any modification to your application's code you can specify debug-only CAs that are +only trusted when android:debuggable +is {@code true} by using {@code debug-overrides}. Normally IDEs and build tools set this flag automatically for non-release builds.

+

This is safer than the usual conditional code because, as a security precaution, application stores +do not accept applications which are marked debuggable.

+ +

+res/xml/network_security_config.xml: +

+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <debug-overrides>
+        <trust-anchors>
+            <certificates src="@raw/debug_cas"/>
+        </trust-anchors>
+    </debug-overrides>
+</network-security-config>
+
+

+

+In AndroidManifest.xml reference the above config +

+<?xml version="1.0" encoding="utf-8"?>
+...
+<application ...>
+    <meta-data android:name="android.security.net.config"
+               android:resource="@xml/network_security_config" />
+    ...
+
+

+ +

Cleartext Traffic Opt-Out

+

Applications which intend to connect to destinations using only secure connections can opt-out +of supporting cleartext (i.e. plain HTTP instead of HTTPS) to those destinations. This helps prevent +accidental regressions in applications due to changes in URLs provided by external sources such as +backend servers.

+

See {a href="{@docRoot}reference/android/security/NetworkSecurityPolicy.html#isCleartextTrafficPermitted()} for more details.

+ +

For example, an application may want to ensure that all connections to {@code secure.example.com} are always +done over HTTPS to protect sensitive traffic from hostile networks.

+ +

+res/xml/network_security_config.xml: +

+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <domain-config usesCleartextTraffic="false">
+        <domain includeSubdomains="true">secure.example.com</domain>
+    </domain-config>
+</network-security-config>
+
+

+

+In AndroidManifest.xml reference the above config +

+<?xml version="1.0" encoding="utf-8"?>
+...
+<application ...>
+    <meta-data android:name="android.security.net.config"
+               android:resource="@xml/network_security_config" />
+    ...
+
+

+ +

Certificate Pinning

+

Normally an application trusts all preinstalled CAs. If any of these CAs were to issue a fradulent certificate +the application would be at risk from a MiTM attack. Some applications choose to limit the set of +certificates they accept by either limiting the set of CAs they trust or by certificate pinning.

+ +

Certificate pinning is done by providing a set of certificates by hash of the public key (SubjectPublicKeyInfo +of the X.509 certificate). A certificate chain is then only valid if the certificate chain contains at least +one of the pinned public keys.

+ +

Note that when using certificate pinning you should always include a backup key so that if you +are forced to switch to new keys, or change CAs (when pinning to a CA certificate or an intermediate of that CA), +your application's connectivity is unaffected. Otherwise you will have to push out an update to the +application to restore connectivity.

+ +

Additionally it is possible to set an expiration time for pins after which pinning will not be +performed. This helps prevent connectivity issues in applications which have not been updated. +However, setting an expiration time on pins may enable pinning bypass. +

+ +

+res/xml/network_security_config.xml: +

+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <domain-config>
+        <domain includeSubdomains="true">example.com</domain>
+        <pin-set expiration="2018-01-01">
+            <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+            <!-- backup pin -->
+            <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
+    </domain-config>
+</network-security-config>
+
+

+

+In AndroidManifest.xml reference the above config +

+<?xml version="1.0" encoding="utf-8"?>
+...
+<application ...>
+    <meta-data android:name="android.security.net.config"
+               android:resource="@xml/network_security_config" />
+    ...
+
+

+ +

Configuration Inheritance

+

Values not set in a specific config will be inherited. +This allows more complex configurations while keeping the configuration file readable.

+ +

If a value is not set in a specific entry then value from the next more general entry will be used. +Values not set in a {@code domain-config} will be taken from the parent {@code domain-config}, if nested, or +from the {@code base-config} if not. Values not set in the {@code base-config} will use +the platform default values. + +

For example consider, where all connections to subdomains of {@code example.com} +must use a custom set of CAs. Additonally cleartext traffic to these domains is permitted +except when connecting to {@code secure.example.com}. By nesting the configuration +for {@code secure.example.com} inside the configuration for {@code example.com} the +{@code trust-anchors} does not need to be duplicated.

+ +

+res/xml/network_security_config.xml: +

+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <domain-config>
+        <domain includeSubdomains="true">example.com</domain>
+        <trust-anchors>
+            <certificates src="@raw/my_ca"/>
+        </trust-anchors>
+        <domain-config cleartextTrafficPermitted="false">
+            <domain includeSubdomains="true">secure.example.com</domain>
+        </domain-config>
+    </domain-config>
+</network-security-config>
+
+

+

+In AndroidManifest.xml reference the above config +

+<?xml version="1.0" encoding="utf-8"?>
+...
+<application ...>
+    <meta-data android:name="android.security.net.config"
+               android:resource="@xml/network_security_config" />
+    ...
+
+

+ +

Configuration File Format

+

The configuration file is XML. Here is what it can contain:

+

+
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <base-config>
+        <trust-anchors>
+            <certificates src="..."/>
+            ...
+        </trust-anchors>
+    </base-config>
+
+    <domain-config>
+        <domain>android.com</domain>
+        ...
+        <trust-anchors>
+            <certificates src="..."/>
+            ...
+        </trust-anchors>
+        <pin-set>
+            <pin digest="...">...</pin>
+            ...
+        </pin-set>
+    </domain-config>
+    ...
+    <debug-overrides>
+        <trust-anchors>
+            <certificates src="..."/>
+            ...
+        </trust-anchors>
+    </debug-overrides>
+</network-security-config>
+
+ +

<network-security-config>

+
+
can contain:
+
0 or 1 <base-config> +
Any number of <domain-config> +
0 or 1<debug-overrides> +
+
+ + +

<base-config>

+
+
syntax:
+
<base-config usesCleartextTraffic=["true" | "false"]>
+    ...
+</base-config>
+
can contain:
+
<trust-anchors>
+
descrption:
+
+The default configuration used by all connections whose destination is not covered by a +domain-config. + +

Any values that are not set will use the platform default values. +The default configuration for applications targeting above API level 24 and above: +

+<base-config usesCleartextTraffic="true">
+    <trust-anchors>
+        <certificates src="system" />
+    </trust-anchors>
+</base-config>
+
+The default configuration for applications targeting API level 23 and below is: +
+<base-config usesCleartextTraffic="true">
+    <trust-anchors>
+        <certificates src="system" />
+        <certificates src="user" />
+    </trust-anchors>
+</base-config>
+
+

+
+
+ +

<domain-config>

+
+
syntax:
+
<domain-config usesCleartextTraffic=["true" | "false"]>
+    ...
+</domain-config>
+
Can Contain:
+ +
+1 or more <domain> +
0 or 1 <trust-anchors> +
0 or 1 <pin-set> +
Any number of nested <domain-config>
+ +
Descrption
+
Configuration used for connections to specific destinations as the defined by {@code domain} elements. + +

Note that if multiple {@code domain-config} elements cover a destination the config with the most specific (longest) +matching domain rule will be used.

+
+ +

<domain>

+
+
syntax:
+
<domain includeSubdomains=["true" | "false"]>example.com</domain>
+
Attributes:
+
+
{@code includeSubdomains}
+
If {@code "true"} then this domain rule will match the domain and all subdomains, including +subdomains of subdomains, otherwise the rule only applies to exact matches.
+
+
+ +
Descrption:
+
+ +

<debug-overrides>

+
+
syntax:
+
<debug-overrides>
+    ...
+</debug-overrides>
+
Can Contain:
+
0 or 1 <trust-anchors>
+
Description:
+
Overrides to be applied when +android:debuggable is +{@code "true"} which is normally the case for non-release builds generated by IDEs and build tools. +Trust anchors specified in {@code debug-overrides} are added to all other configurations and certificate +pinning is not performed when the server's certificate chain uses one of these debug-only trust anchors. +If android:debuggable is +{@code "false"} then this section is completely ignored. +
+
+ +

<trust-anchors>

+
+
syntax:
+
+
<trust-anchors>
+...
+</trust-anchors>
+
+
Can Contain:
+
Any number of <certificates>
+
Description:
+
Set of trust anchors for secure connections.
+
+ + +

<certificates>

+
+
syntax:
+
<certificates src=["system" | "user" | "raw resource"]
+              overridePins=["true" | "false"] />
+
+
description:
+
Set of X.509 certificates for {@code trust-anchors} elements.
+ +
attributes:
+
+
{@code src}
+
+The source of CA certificates, can be one of +
    +
  • a raw resource id pointing to a file containing X.509 certificates. Certificates must be encoded in DER or PEM format. + In the case of PEM certificates the file must not contain extra non-PEM data such as comments.
  • +
  • {@code "system"} for the pre-installed system CA certificates
  • +
  • {@code "user"} for user-added CA certificates
  • +
+
+ +
{@code overridePins}
+
+Specifies if the CAs from this source bypass certificate pinning. If {@code "true"} then certificate chains which +chain through one of the CAs from this source then pinning will not be performed. This can be useful +for debug CAs or to support letting the user MiTM your app's secure traffic. +

+Default is {@code "false"} unless specified in a {@code debug-overrides} element, in which case the default is {@code "true"}. +

+
+
+
+ +

<pin-set>

+
+
syntax:
+
+
<pin-set expiration="date">
+...
+</pin-set>
+
+
Can Contain:
+
Any number of <pin>
+
Description:
+
A set of public key pins. For a secure connection to be trusted, one of the public keys in the chain of trust must +be in the set of pins. See <pin> for the format of pins.
+
Attributes:
+
+
{@code expiration}
+
The date, in {@code yyyy-MM-dd} format, at and after which the pins expire, thus disabling pinning. +If the attribute is not set then the pins do not expire. +

Expiration helps prevent connectivity issues in applications which do not get updates to their +pin set, for example because the user disabled application updates.

+
+
+
+ +

<pin>

+
+
syntax:
+
+
<pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>
+
Attributes:
+
+
{@code digest}
+
The digest algorithm used to generate the pin. Currently only {@code "SHA-256"} is supported.
+
+
+