Bloqueie o texto não criptografado em apps Android sem depender de uma VPN
Texto não criptografado na carga e texto não criptografado no caminho são problemas diferentes. Corrija o primeiro no app e o segundo com um túnel ou uma política de dispositivo.
Duas coisas muito diferentes recebem o nome de bloquear texto não criptografado no Android. Uma é uma política dentro de um app que manda a própria pilha de rede recusar HTTP simples. A outra é um arranjo no nível do dispositivo que tenta proteger tudo no telefone de uma vez, normalmente encaminhando o tráfego por uma VPN. Elas resolvem problemas diferentes, e a segunda não pode corrigir a primeira: um túnel protege o trecho entre o telefone e a saída, enquanto um app que fala HTTP continua falando HTTP com tudo o que está além dessa saída.
Dois problemas com um só nome
O primeiro problema é a carga: o app grava credenciais ou tokens numa requisição que não é criptografada de ponta a ponta, então cada salto que consegue vê-la consegue lê-la. O segundo é o caminho: o app pode estar perfeitamente correto, e você ainda quer que o operador de Wi-Fi local não aprenda nada sobre onde ele se conecta. Uma VPN trata do segundo e só do segundo.
Essa distinção decide de quem é a correção. A carga pertence a quem distribui o app, porque só esse código decide qual URL é chamada e se um certificado é validado. O caminho pertence ao dispositivo ou à rede, porque a questão é por onde os pacotes viajam, não o que eles contêm.
Caminho um: o app que você controla
Se você distribui o app, a correção é uma decisão de transporte mais uma política que a impõe. Aponte cada endpoint para HTTPS, mantenha a validação de nome de host e certificado ligada, e apague o recurso ao HTTP simples em vez de deixá-lo a uma flag de configuração de distância. Um redirecionamento não ajuda aqui: uma requisição HTTP que recebe um 301 já enviou cabeçalhos e corpo em claro, então credenciais nunca devem viajar supondo que o redirecionamento as protegerá.
No Android 7.0 e posteriores, o Network Security Configuration expressa a política. O arquivo abaixo é a menor versão útil: recusa texto não criptografado em toda parte, a menos que uma exceção específica de domínio diga o contrário.
<network-security-config>
<base-config cleartextTrafficPermitted="false" />
</network-security-config>Referencie esse recurso no manifesto e depois leia as exceções que já existem antes de distribuir. Um domínio antigo de depuração ou uma entrada de SDK de provedor de pagamentos pode voltar a permitir texto não criptografado em silêncio para o host que você tentava proteger.
Dois detalhes de versão valem ser conhecidos. Apps que miram a API 28 ou superior já recusam texto não criptografado por padrão, então um app que ainda fala HTTP simples ou mira um nível de API mais antigo ou tem uma exceção em algum lugar. E quando existe uma configuração de segurança de rede, o atributo de manifesto mais antigo android:usesCleartextTraffic já não decide a questão, e é por isso que mudar essa flag às vezes parece não fazer nada.
Caminho dois: o app que você não controla
Para um app de terceiros instalado, você não pode reescrever a configuração de segurança com um ajuste de usuário. As opções realistas são os controles de conexão segura do próprio produto, uma alternativa mantida que já use TLS, ou uma política de dispositivo gerenciado que limite o que o dispositivo pode executar. São compromissos diferentes, e só o terceiro escala para um parque de dispositivos.
As regras de rede são substitutas mais fracas do que parecem. Permitir só a porta 443 não impõe TLS autenticado, porque muitos protocolos de texto não criptografado podem ser movidos para essa porta, e bloquear a porta 80 não cobre o texto não criptografado em outras portas. O modo somente HTTPS de um navegador também fica restrito a esse navegador, não a um app de e-mail ou chat separado no mesmo telefone.
Instalar um certificado de interceptação para o tráfego parecer criptografado é uma mudança de confiança, não uma correção. Ele substitui a autenticação de servidor do app pela sua, e um app que não validava certificados desde o início não é consertado por isso; você apenas moveu quem pode ler o fluxo.
Onde uma VPN ajuda e onde não
Um túnel é a ferramenta certa quando o requisito é que a rede local não aprenda nada sobre a conexão, ou que o app alcance um serviço privado a que de outro modo não chega. É a ferramenta errada para fazer um cliente HTTP falar HTTPS, porque a requisição sai do túnel exatamente como entrou.
O Android acrescenta uma restrição prática: a plataforma executa um único serviço de VPN por vez. Um app de filtragem local que ocupa esse lugar compete com o túnel remoto de que você realmente precisa, e alternar entre os dois é uma operação no nível do dispositivo, não do app. Esse único lugar é uma boa razão para manter a política de carga no app e reservar o túnel para o caminho.
O único caso em que os dois se sobrepõem é um servidor privado que você também opera. Ali um túnel pode tornar o caminho privado mesmo que o protocolo continue sendo texto não criptografado, o que reduz a exposição mas não muda o que é a carga. Trate isso como redução de risco, não como criptografia dos dados.
O que testar antes de dar isso como bloqueado
Comece pelo padrão que surpreende as pessoas: um app que mira a API 28 ou superior já deveria recusar texto não criptografado, então confira o nível de destino antes de acrescentar configuração que duplique um padrão. Depois teste o caso de falha de propósito: uma requisição a um host HTTP simples deve falhar, não ter sucesso em silêncio por meio de um recurso alternativo.
adb shell dumpsys package com.example.app | grep -E 'targetSdk|versionName'
adb logcat | grep -i cleartextPara o caso de sucesso, confirme que a chamada HTTPS valida uma cadeia de certificados real e que um proxy com certificado não confiável é recusado em vez de tolerado. Um aperto de mão que tem sucesso contra qualquer certificado não provou nada sobre a segurança do transporte.
Para um app de terceiros, anote o limite que você realmente pode impor, seja uma política de dispositivo gerenciado, uma regra de rede ou nada, e diga isso nos critérios de aceitação. O guia de configuração de segurança do Android lista os padrões da plataforma e quais componentes respeitam a política, e é essa parte que decide se a sua configuração faz alguma coisa.