O recurso de configurações de segurança de rede permite personalizar as definições de segurança de rede do seu app em um arquivo de configuração seguro e declarativo sem modificar o código do app. Essas configurações podem ser definidas para domínios específicos e para um determinado app. Os principais atributos do recurso são:
- Âncoras de confiança personalizadas: personaliza quais autoridades certificadoras (AC) são confiáveis para as conexões seguras de um app. Por exemplo, confiar em certificados autoassinados particulares ou restringir o conjunto de ACs públicas em que o app confia.
- Substituições somente de depuração: depura conexões seguras do app, sem adicionar riscos à base instalada.
- Cancelamento do uso de tráfego de texto simples: protege apps contra o uso acidental de tráfego de texto simples.
- Ativar a transparência de certificados:restrinja as conexões seguras de um app para usar certificados registrados de forma comprovada.
- Fixação de certificados: restringe a conexão segura de um app a certificados específicos.
Adicionar um arquivo de configurações de segurança de rede
O recurso de configurações de segurança de rede usa um arquivo XML em que você especifica as configurações do seu app. Inclua uma entrada no manifesto do app que aponte para esse arquivo. Este exemplo de código de um manifesto demonstra como criar essa entrada:
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application> </manifest>
Personalizar ACs confiáveis
Você pode querer que seu app confie em um conjunto personalizado de ACs em vez de no padrão da plataforma. Estes são os motivos mais comuns para isso:
- Conectar-se a um host com uma AC personalizada, como uma AC autoassinada ou emitida internamente em uma empresa.
- Limitar o conjunto de ACs para apenas aquelas em que você confia, em vez de todas as pré-instaladas.
- Confiar em outras ACs não incluídas no sistema.
Por padrão, conexões seguras (que usam protocolos como TLS e HTTPS) de todos
os apps confiam nas ACs pré-instaladas do sistema, e os apps destinados ao Android 6.0 (nível 23
da API) e versões anteriores também confiam no repositório de ACs adicionadas pelo usuário por padrão. Você pode
personalizar as conexões do seu app usando base-config
(para personalização
em todo o app) ou domain-config
(para personalização por domínio).
Configurar uma AC personalizada
É possível se conectar a um host que use um certificado
SSL autoassinado ou a um host cujo certificado SSL seja emitido por uma AC não pública
em que você confia, como a AC interna da sua empresa.
O exemplo de código abaixo demonstra como configurar seu app para uma AC personalizada
em 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>
Adicione o certificado da AC autoassinado ou não público em formato PEM ou DER em
res/raw/my_ca
.
Limitar o conjunto de ACs confiáveis
Se você não quiser que seu app confie em todas as ACs em que o sistema confia, especifique um conjunto reduzido de ACs confiáveis. Isso protege o app contra certificados fraudulentos emitidos por qualquer outra AC.
A configuração para limitar o conjunto de ACs confiáveis é semelhante a confiar em uma AC personalizada para um domínio específico, mas
fornecendo várias ACs no recurso.
O exemplo de código abaixo demonstra como limitar o conjunto de ACs confiáveis do seu app
em 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>
Adicione as ACs confiáveis em formato PEM ou DER em res/raw/trusted_roots
.
Se você usar o formato PEM, o arquivo precisa conter apenas dados PEM,
sem texto extra. Você também pode fornecer vários elementos
<certificates>
em vez de apenas um.
Confiar em outras ACs
Talvez você queira que seu app confie em outras ACs em que o
sistema não confia. Por exemplo, se o sistema ainda não incluir a AC ou se ela não
atender aos requisitos para inclusão no sistema Android. É possível especificar
várias fontes de certificados para uma configuração em
res/xml/network_security_config.xml
usando um código como o trecho abaixo.
<?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>
Configurar ACs para depuração
Ao depurar um app conectado por HTTPS, é recomendável que você se
conecte a um servidor de desenvolvimento local que não tenha o certificado
SSL do seu servidor de produção. Para fazer isso sem
modificar o código do app, você pode usar debug-overrides
para especificar ACs somente de depuração que
sejam confiáveis somente quando o elemento android:debuggable
for true
. Normalmente, ambientes de desenvolvimento integrado e ferramentas
de build definem essa flag automaticamente para builds que não são de lançamento.
Isso é mais seguro do que o código condicional normal, porque, como medida de segurança, os repositórios do app não aceitam apps marcados como depuráveis.
O trecho abaixo mostra como especificar ACs somente de depuração em
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>
Ativar a transparência dos certificados
A Transparência dos certificados (CT, RFC 9162) é um padrão da Internet desenvolvido para melhorar a segurança dos certificados digitais. Ele exige que as ACs enviem todos os certificados emitidos para um registro público que os registra, aumentando a transparência e a responsabilidade no processo de emissão de certificados.
Ao manter um registro verificável de todos os certificados, a CT dificulta muito a falsificação de certificados por usuários mal-intencionados ou a emissão deles por ACs por engano. Isso ajuda a proteger os usuários contra ataques "man-in-the-middle" e outras ameaças de segurança. Para mais informações, consulte a explicação em transparency.dev.
Por padrão, os certificados são aceitos, independentemente de estarem registrados em um registro de CT. Para garantir que o app se conecte apenas a destinos com certificados registrados em um registro de CT, você pode ativar o recurso globalmente ou por domínio.
Cancelar uso de tráfego de texto simples
Observação: a orientação desta seção se aplica apenas aos apps destinados ao Android 8.1 (nível 27 da API) ou versões anteriores. No Android 9 (nível 28 da API) e mais recentes, o suporte a texto não criptografado fica desativado por padrão.
Se você pretende que seu app se conecte a destinos usando apenas conexões
seguras, desative o suporte a texto não criptografado (usando o protocolo HTTP
não criptografado em vez de HTTPS) para esses destinos. Essa opção ajuda a evitar
regressões acidentais em apps devido a mudanças nos URLs fornecidos por fontes
externas, por exemplo, servidores de back-end.
Consulte NetworkSecurityPolicy.isCleartextTrafficPermitted()
para mais detalhes.
Por exemplo, você pode querer que seu app garanta que as conexões com
secure.example.com
sejam sempre realizadas por HTTPS para proteger o tráfego confidencial
de redes hostis.
O exemplo abaixo mostra como desativar o texto não criptografado em
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </network-security-config>
Fixar certificados
Normalmente, um app confia em todas as ACs pré-instaladas. Se qualquer uma dessas ACs emitir um certificado fraudulento, um invasor no caminho poderá comprometer o app. Alguns apps optam por limitar o conjunto de certificados que aceitam restringindo o conjunto de ACs ou fixando certificados.
A fixação de certificados é realizada ao fornecer um conjunto de certificados pelo hash da
chave pública (SubjectPublicKeyInfo
do certificado X.509). Uma
cadeia de certificados é válida somente se contiver
pelo menos uma das chaves públicas fixadas.
Ao usar a fixação de certificados, é preciso sempre incluir uma chave de backup para que, se você precisar alternar para novas chaves ou mudar as ACs (ao fixar um certificado da AC ou um intermediário dela), a conectividade do seu app não seja afetada. Caso contrário, será necessário enviar uma atualização ao app para restaurar a conectividade.
Além disso, é possível definir um tempo de expiração para as fixações, para que depois disso elas não sejam mais realizadas. Isso ajuda a evitar problemas de conectividade em apps que não foram atualizados. No entanto, definir um prazo de validade para fixações pode permitir que invasores ignorem seus certificados fixados.
O exemplo abaixo mostra como fixar certificados em
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> </pin-set> </domain-config> </network-security-config>
Comportamento de herança de configuração
Valores não definidos em uma configuração específica são herdados. Esse comportamento permite configurações mais complexas, mantendo o arquivo de configuração legível.
Por exemplo, valores não definidos em uma domain-config
são obtidos pela domain-config
mãe, se aninhados, ou,
caso contrário, pela base-config
. Valores não definidos no base-config
usam os
valores padrão da plataforma.
Por exemplo, considere um caso em que todas as conexões para subdomínios de example.com
precisam usar um conjunto personalizado de ACs. Além disso, o tráfego de texto simples para
esses domínios é permitido exceto ao se conectar com secure.example.com
.
Ao aninhar a configuração para secure.example.com
dentro da configuração
para example.com
, o
trust-anchors
não precisa ser duplicado.
O trecho abaixo mostra como esse aninhamento ficaria em
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>
Formato do arquivo de configurações
O recurso de configurações de segurança de rede usa um formato do arquivo XML. A estrutura geral desse arquivo é mostrada no exemplo de código abaixo:
<?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>
As seções abaixo descrevem a sintaxe e outros detalhes do formato do arquivo.
<network-security-config>
- Pode conter:
-
0 ou 1
<base-config>
Qualquer quantidade de<domain-config>
0 ou 1<debug-overrides>
<base-config>
- Sintaxe:
<base-config cleartextTrafficPermitted=["true" | "false"]> ... </base-config>
- Pode conter:
-
<trust-anchors>
<certificateTransparency>
- Descrição:
-
A configuração padrão usada por todas as conexões cujo destino não é
coberto por uma
domain-config
.Qualquer valor não definido usa os valores padrão da plataforma.
A configuração padrão para apps destinados ao Android 9 (nível 28 da API) e versões mais recentes é esta:
<base-config cleartextTrafficPermitted="false"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
A configuração padrão para apps destinados ao Android 7.0 (nível 24 da API) até o Android 8.1 (nível 27 da API) é esta:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
A configuração padrão para apps destinados ao Android 6.0 (nível 23 da API) e versões anteriores é esta:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config>
<domain-config>
- Sintaxe:
-
<domain-config cleartextTrafficPermitted=["true" | "false"]> ... </domain-config>
- pode conter:
-
1 ou mais
<domain>
0 ou 1<certificateTransparency>
0 ou 1<trust-anchors>
0 ou 1<pin-set>
Qualquer número de<domain-config>
aninhados - descrição:
- A configuração usada para conexões com destinos específicos, conforme definida pelos
elementos
domain
.Observe que, se vários elementos
domain-config
cobrirem um destino, a configuração com a regra de domínio correspondente mais específica (mais longa) será usada.
<domain>
- Sintaxe:
-
<domain includeSubdomains=["true" | "false"]>example.com</domain>
- Atributos:
-
-
includeSubdomains
-
Se for
"true"
, a regra de domínio corresponderá ao domínio e a todos os subdomínios, incluindo subdomínios de subdomínios. Caso contrário, a regra se aplicará apenas a correspondências exatas.
-
<certificateTransparency>
- Sintaxe:
-
<certificateTransparency enabled=["true" | "false"]/>
- descrição:
-
Se
true
, o app vai usar os registros de transparência de certificados para validar certificados. Quando um app usa o próprio certificado (ou o armazenamento de usuários), é provável que ele não seja público e, portanto, não seja verificável usando a transparência de certificados. Por default, a verificação é desativada nesses casos. Ainda é possível forçar a verificação usando<certificateTransparency enabled="true"/>
na configuração do domínio. Para cada<domain-config>
, a avaliação segue esta ordem:- Se
certificateTransparency
estiver ativado, ative a verificação. -
Se algum
<trust-anchors>
for"user"
ou inline (ou seja,"@raw/cert.pem"
), desative a verificação. - Caso contrário, use a configuração herdada.
- Se
<debug-overrides>
- Sintaxe:
-
<debug-overrides> ... </debug-overrides>
- Pode conter:
-
0 ou 1
<trust-anchors>
- Descrição:
-
Substituições a serem aplicadas quando android:debuggable
for
"true"
, o que normalmente ocorre em builds que não são de lançamento gerados por ambientes de desenvolvimento integrado e ferramentas de build. Âncoras de confiança especificadas emdebug-overrides
são adicionadas a todas as demais configurações e a fixação de certificados não é realizada quando a cadeia de certificados do servidor usa uma dessas âncoras de confiança somente de depuração. Se android:debuggable for"false"
, esta seção será ignorada por completo.
<trust-anchors>
- Sintaxe:
-
<trust-anchors> ... </trust-anchors>
- Pode conter:
-
Qualquer quantidade de
<certificates>
- Descrição:
- Conjunto de âncoras de confiança para conexões seguras.
<certificates>
- Sintaxe:
<certificates src=["system" | "user" | "raw resource"] overridePins=["true" | "false"] />
- Descrição:
- Conjunto de certificados X.509 para elementos
trust-anchors
. - Atributos:
-
src
-
A fonte de certificados de AC. Os certificados podem ser destes tipos:
- Um ID de recurso bruto que aponta para um arquivo que contém certificados X.509. Os certificados precisam ser codificados em formato DER ou PEM. No caso de certificados PEM, o arquivo não pode conter dados não PEM extras, como comentários.
"system"
para certificados de AC pré-instalados do sistema"user"
para certificados de AC adicionados pelo usuário
overridePins
-
Especifica se as ACs dessa fonte ignoram a fixação de certificados. Se for
"true"
, a fixação não será realizada em cadeias de certificados que são assinados por uma das ACs dessa fonte. Isso pode ser útil para depurar ACs ou para testar ataques de interceptação no tráfego seguro do seu app.O padrão é
"false"
a não ser que seja especificado em um elementodebug-overrides
. Nesse caso, o padrão será"true"
.
<pin-set>
- Sintaxe:
-
<pin-set expiration="date"> ... </pin-set>
- Pode conter:
-
Qualquer quantidade de
<pin>
- Descrição:
-
Um conjunto de fixações de chave pública. Para que uma conexão segura seja confiável, uma das
chaves públicas na cadeia de confiança precisa estar presente no conjunto de fixações. Consulte
<pin>
para saber mais sobre o formato das fixações. - Atributos:
-
-
expiration
-
A data, no formato
yyyy-MM-dd
, na qual as fixações expiram e são desativadas. Se o atributo não for definido, as fixações não vão expirar.A expiração ajuda a evitar problemas de conectividade em apps que não recebem atualizações para o conjunto de fixações, por exemplo, quando o usuário desativa as atualizações do app.
-
<pin>
- Sintaxe:
-
<pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>
- Atributos:
-
-
digest
-
O algoritmo de resumo usado para gerar a fixação. Atualmente, só
há suporte para
"SHA-256"
.
-
Outros recursos
Para mais informações sobre configurações de segurança de rede, consulte os recursos abaixo.