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
540 lines
20 KiB
Plaintext
540 lines
20 KiB
Plaintext
page.title=Network Security Config
|
|
@jd:body
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
|
|
<h2>In this document</h2>
|
|
<ol>
|
|
<li><a href="#SupportedFeatures">Features</a></li>
|
|
<li><a href="#Examples">Examples</a>
|
|
<ol>
|
|
<li><a href="#TrustingCustomCas">Trusting Custom CAs</a>
|
|
<ol>
|
|
<li><a href="#TrustingACustomCa">Trusting a Custom CA</a></li>
|
|
<li><a href="#LimitingCas">Limiting the Set of Trusted CAs</a></li>
|
|
<li><a href="#TrustingAdditionalCas">Trusting Additional CAs</a></li>
|
|
</ol>
|
|
</li>
|
|
<li><a href="#TrustingDebugCa">Debugging-only CAs</a></li>
|
|
<li><a href="#UsesCleartextTraffic">Cleartext Traffic Opt-Out</a></li>
|
|
<li><a href="#CertificatePinning">Certificate Pinning</a></li>
|
|
<li><a href="#ConfigInheritance">Configuration Inheritance</a></li>
|
|
</ol>
|
|
</li>
|
|
<li><a href="#FileFormat">Configuration File Format</a></li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
|
|
<p>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.</p>
|
|
|
|
<h2 id="SupportedFeatures">Features</h2>
|
|
<ul>
|
|
<li><b>Custom trust anchors.</b> Lets an application customize which Certificate Authorities (CA) are trusted
|
|
for its secure connections. For example, trusting particular self-signed certificates or restricting the set of public
|
|
CAs that the app trusts.
|
|
</li>
|
|
<li><b>Debug-only overrides.</b> Lets an application developer safely debug secure connections of their
|
|
application without added risk to the installed base.
|
|
</li>
|
|
<li><b>Cleartext traffic opt-out.</b> Lets an application protect itself from accidental usage of cleartext traffic.</li>
|
|
<li><b>Certificate pinning.</b> An advanced feature that lets an application restrict pin its secure connection
|
|
to particular certificates.</li>
|
|
</ul>
|
|
|
|
<h2 id="Examples">Examples</h2>
|
|
<h3 id="TrustingCustomCas">Trusting Custom CAs</h3>
|
|
<p>An application may want to trust a custom set of CAs instead of the platform
|
|
default. The most common reasons of this are:
|
|
<ul>
|
|
<li>Connecting to a host with a custom certificate authority(self-signed, issued by an internal corporate CA, etc).</li>
|
|
<li>Limiting the set of CAs to only the CAs you trust instead of every preinstalled CA.</li>
|
|
<li>Trusting additional CAs not included in the system.</li>
|
|
</ul>
|
|
</p>
|
|
<p>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).</p>
|
|
|
|
<h4 id="TrustingACustomCa">Trusting a Custom CA</h4>
|
|
<p>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.</p>
|
|
<p>
|
|
<code>res/xml/network_security_config.xml</code>:
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
</p>
|
|
<p>Add the self-signed or non-public CA certificate, in PEM or DER format, to {@code res/raw/my_ca}.</p>
|
|
<p>
|
|
In <code>AndroidManifest.xml</code> reference the above config
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
...
|
|
<application ...>
|
|
<meta-data android:name="android.security.net.config"
|
|
android:resource="@xml/network_security_config" />
|
|
...
|
|
</pre>
|
|
</p>
|
|
<h4 id="LimitingCas">Limiting the Set of Trusted CAs</h4>
|
|
<p>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.</p>
|
|
|
|
<p>The config to limit the set of trusted CAs is similar to <a href="#TrustingACustomCa">trusting a custom CA</a>
|
|
for a specific domain except that multiple CAs are provided in the resource.</p>
|
|
|
|
<p>
|
|
<code>res/xml/network_security_config.xml</code>:
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
</p>
|
|
<p>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 <em>only</em> PEM data and no extra text.
|
|
You can also provide multiple <a href="certificates"><code><certificates></code></a> elements instead
|
|
of one.</p>
|
|
<p>
|
|
In <code>AndroidManifest.xml</code> reference the above config
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
...
|
|
<application ...>
|
|
<meta-data android:name="android.security.net.config"
|
|
android:resource="@xml/network_security_config" />
|
|
...
|
|
</pre>
|
|
</p>
|
|
|
|
<h4 id="TrustingAdditionalCas">Trusting Additional CAs</h4>
|
|
<p>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.
|
|
</p>
|
|
<p>
|
|
<code>res/xml/network_security_config.xml</code>:
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
</p>
|
|
<p>
|
|
In <code>AndroidManifest.xml</code> reference the above config
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
...
|
|
<application ...>
|
|
<meta-data android:name="android.security.net.config"
|
|
android:resource="@xml/network_security_config" />
|
|
...
|
|
</pre>
|
|
</p>
|
|
|
|
<h3 id="TrustingDebugCa">Debugging-only CAs</h3>
|
|
<p>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
|
|
<i>only</i> trusted when <a href="{@docRoot}guide/topics/manifest/application-element.html#debug">android:debuggable</a>
|
|
is {@code true} by using {@code debug-overrides}. Normally IDEs and build tools set this flag automatically for non-release builds.</p>
|
|
<p>This is safer than the usual conditional code because, as a security precaution, application stores
|
|
do not accept applications which are marked debuggable.</p>
|
|
|
|
<p>
|
|
<code>res/xml/network_security_config.xml</code>:
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
</p>
|
|
<p>
|
|
In <code>AndroidManifest.xml</code> reference the above config
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
...
|
|
<application ...>
|
|
<meta-data android:name="android.security.net.config"
|
|
android:resource="@xml/network_security_config" />
|
|
...
|
|
</pre>
|
|
</p>
|
|
|
|
<h3 id="UsesCleartextTraffic">Cleartext Traffic Opt-Out</h3>
|
|
<p>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.</p>
|
|
<p>See {a href="{@docRoot}reference/android/security/NetworkSecurityPolicy.html#isCleartextTrafficPermitted()} for more details.</p>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>
|
|
<code>res/xml/network_security_config.xml</code>:
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
</p>
|
|
<p>
|
|
In <code>AndroidManifest.xml</code> reference the above config
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
...
|
|
<application ...>
|
|
<meta-data android:name="android.security.net.config"
|
|
android:resource="@xml/network_security_config" />
|
|
...
|
|
</pre>
|
|
</p>
|
|
|
|
<h3 id="CertificatePinning">Certificate Pinning</h3>
|
|
<p>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.</p>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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.
|
|
</p>
|
|
|
|
<p>
|
|
<code>res/xml/network_security_config.xml</code>:
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
</p>
|
|
<p>
|
|
In <code>AndroidManifest.xml</code> reference the above config
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
...
|
|
<application ...>
|
|
<meta-data android:name="android.security.net.config"
|
|
android:resource="@xml/network_security_config" />
|
|
...
|
|
</pre>
|
|
</p>
|
|
|
|
<h3 id="ConfigInheritance">Configuration Inheritance</h3>
|
|
<p>Values not set in a specific config will be inherited.
|
|
This allows more complex configurations while keeping the configuration file readable.</p>
|
|
|
|
<p>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.
|
|
|
|
<p>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
|
|
<em>except</em> 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.</p>
|
|
|
|
<p>
|
|
<code>res/xml/network_security_config.xml</code>:
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
</p>
|
|
<p>
|
|
In <code>AndroidManifest.xml</code> reference the above config
|
|
<pre>
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
...
|
|
<application ...>
|
|
<meta-data android:name="android.security.net.config"
|
|
android:resource="@xml/network_security_config" />
|
|
...
|
|
</pre>
|
|
</p>
|
|
|
|
<h2 id="FileFormat">Configuration File Format</h2>
|
|
<p>The configuration file is XML. Here is what it can contain:</p>
|
|
</p>
|
|
<pre>
|
|
<?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>
|
|
</pre>
|
|
|
|
<h3 id="network-security-config"><network-security-config></h3>
|
|
<dl class="xml">
|
|
<dt>can contain:</dt>
|
|
<dd>0 or 1 <code><a href="#base-config"><base-config></a></code>
|
|
<br/>Any number of <code><a href="#domain-config"><domain-config></a></code>
|
|
<br/>0 or 1<code><a href="#debug-overrides"><debug-overrides></a></code>
|
|
</dd>
|
|
</dl>
|
|
|
|
|
|
<h3 id="base-config"><base-config></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd><pre class="stx"><base-config <a href="#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]>
|
|
...
|
|
</base-config></pre></dd>
|
|
<dt>can contain:</dt>
|
|
<dd><code><a href="#trust-anchors"><trust-anchors></a></code></dd>
|
|
<dt>descrption:</dt>
|
|
<dd>
|
|
The default configuration used by all connections whose destination is not covered by a
|
|
<a href="#domain-config"><code>domain-config</code></a>.
|
|
|
|
<p>Any values that are not set will use the platform default values.
|
|
The default configuration for applications targeting above API level 24 and above:
|
|
<pre>
|
|
<base-config usesCleartextTraffic="true">
|
|
<trust-anchors>
|
|
<certificates src="system" />
|
|
</trust-anchors>
|
|
</base-config>
|
|
</pre>
|
|
The default configuration for applications targeting API level 23 and below is:
|
|
<pre>
|
|
<base-config usesCleartextTraffic="true">
|
|
<trust-anchors>
|
|
<certificates src="system" />
|
|
<certificates src="user" />
|
|
</trust-anchors>
|
|
</base-config>
|
|
</pre>
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3 id="domain-config"><domain-config></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd><pre class="stx"><domain-config <a href="#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]>
|
|
...
|
|
</domain-config></pre></dd>
|
|
<dt>Can Contain:</dt>
|
|
|
|
<dd>
|
|
1 or more <code><a href="#domain"><domain></a></code>
|
|
<br/>0 or 1 <code><a href="#trust-anchors"><trust-anchors></a></code>
|
|
<br/>0 or 1 <code><a href="#pin-set"><pin-set></code></a>
|
|
<br/>Any number of nested <code><domain-config></code></dd>
|
|
|
|
<dt>Descrption</dt>
|
|
<dd>Configuration used for connections to specific destinations as the defined by {@code domain} elements.
|
|
|
|
<p>Note that if multiple {@code domain-config} elements cover a destination the config with the most specific (longest)
|
|
matching domain rule will be used.</p></dd>
|
|
</dl>
|
|
|
|
<h3 id="domain"><domain></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd><pre class="stx"><domain includeSubdomains=["true" | "false"]>example.com</domain></pre></dd>
|
|
<dt>Attributes:</dt>
|
|
<dd><dl class="attr">
|
|
<dt>{@code includeSubdomains}</dt>
|
|
<dd>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.</dd>
|
|
</dl>
|
|
</dd>
|
|
|
|
<dt>Descrption:</dt>
|
|
</dl>
|
|
|
|
<h3 id="debug-overrides"><debug-overrides></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd><pre class="stx"><debug-overrides>
|
|
...
|
|
</debug-overrides></pre></dd>
|
|
<dt>Can Contain:</dt>
|
|
<dd>0 or 1 <code><a href="#trust-anchors"><trust-anchors></a></code></dd>
|
|
<dt>Description:</dt>
|
|
<dd>Overrides to be applied when
|
|
<a href="{@docRoot}guide/topics/manifest/application-element.html#debug">android:debuggable</a> 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 <a href="{@docRoot}guide/topics/manifest/application-element.html#debug">android:debuggable</a> is
|
|
{@code "false"} then this section is completely ignored.
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3 id="trust-anchors"><trust-anchors></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd>
|
|
<pre class="stx"><trust-anchors>
|
|
...
|
|
</trust-anchors>
|
|
</pre></dd>
|
|
<dt>Can Contain:</dt>
|
|
<dd>Any number of <code><a href="#certificates"><certificates></a></code></dd>
|
|
<dt>Description:</dt>
|
|
<dd>Set of trust anchors for secure connections.</dd>
|
|
</dl>
|
|
|
|
|
|
<h3 id="certificates"><certificates></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd><pre class="stx"><certificates src=["system" | "user" | "<i>raw resource</i>"]
|
|
overridePins=["true" | "false"] />
|
|
</pre></dd>
|
|
<dt>description:</dt>
|
|
<dd>Set of X.509 certificates for {@code trust-anchors} elements.</dd>
|
|
|
|
<dt>attributes:</dt>
|
|
<dd><dl class="attr">
|
|
<dt>{@code src}</dt>
|
|
<dd>
|
|
The source of CA certificates, can be one of
|
|
<ul>
|
|
<li>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 <em>must not</em> contain extra non-PEM data such as comments.</li>
|
|
<li>{@code "system"} for the pre-installed system CA certificates</li>
|
|
<li>{@code "user"} for user-added CA certificates</li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dt>{@code overridePins}</dt>
|
|
<dd>
|
|
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.
|
|
<p>
|
|
Default is {@code "false"} unless specified in a {@code debug-overrides} element, in which case the default is {@code "true"}.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
|
|
<h3 id="pin-set"><pin-set></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd>
|
|
<pre class="stx"><pin-set expiration="date">
|
|
...
|
|
</pin-set>
|
|
</pre></dd>
|
|
<dt>Can Contain:</dt>
|
|
<dd>Any number of <code><a href="#pin"><pin></a></code></dd>
|
|
<dt>Description:</dt>
|
|
<dd>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 <code><a href="#pin"><pin></a></code> for the format of pins.</dd>
|
|
<dt>Attributes:</dt>
|
|
<dd><dl class="attr">
|
|
<dt>{@code expiration}</dt>
|
|
<dd>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.
|
|
<p>Expiration helps prevent connectivity issues in applications which do not get updates to their
|
|
pin set, for example because the user disabled application updates.</p>
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
|
|
<h3 id="pin"><pin></h3>
|
|
<dl class="xml">
|
|
<dt>syntax:</dt>
|
|
<dd>
|
|
<pre class="stx"><pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin></pre></dd>
|
|
<dt>Attributes:</dt>
|
|
<dd><dl class="attr">
|
|
<dt>{@code digest}</dt>
|
|
<dd>The digest algorithm used to generate the pin. Currently only {@code "SHA-256"} is supported.</dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|