Segurança avançada de Rede | Artigo | Flutter
- Segurança avançada de Rede | Artigo | Flutter
Artigo - Advanced Network Security for Flutter: Certificate Pinning, TLS and Zero-Trust Mobile Architecture🔗 Clique aqui
1. Contexto e Motivação
Aplicações Flutter modernas frequentemente operam em ambientes hostis por definição:
- Redes públicas (Wi-Fi aberto, proxies corporativos)
- Dispositivos fora do controle da organização
- Possibilidade de certificados maliciosos instalados no sistema
- Engenharia reversa do aplicativo
O artigo destaca que HTTPS padrão não é suficiente para aplicações de alta criticidade. Mesmo com TLS ativo, um atacante pode realizar Man-in-the-Middle (MitM) caso consiga:
- Instalar um CA confiável no dispositivo
- Explorar falhas de validação de certificado
- Usar proxies TLS em dispositivos comprometidos
Por isso, o artigo propõe defesa em profundidade, combinando:
- TLS corretamente configurado
- Certificate / Public Key Pinning
- Princípios de Zero-Trust aplicados ao mobile
2. Onde esse tipo de estratégia é utilizado
📌 Conforme descrito no artigo, essas estratégias são usadas principalmente em:
- Aplicativos bancários e fintechs
- Aplicações de pagamento e carteiras digitais
- Apps corporativos com dados proprietários
- Aplicações de saúde (dados sensíveis)
- Aplicações governamentais
- Apps que expõem APIs privadas críticas
Nesses contextos, o impacto de um MitM inclui:
- Roubo de tokens JWT
- Sequestro de sessão
- Vazamento de dados sensíveis
- Fraude financeira
- Comprometimento de contas
3. TLS no Flutter
Flutter utiliza as bibliotecas TLS nativas do sistema operacional:
- Android: BoringSSL
- iOS: SecureTransport / Network.framework
Por padrão, o Flutter:
- Confia no trust store do sistema
- Aceita qualquer CA confiável pelo OS
- Pode aceitar certificados instalados manualmente
⚠️ Isso significa que o aplicativo herda qualquer confiança que o sistema operacional conceder, o que é insuficiente em cenários de ameaça elevada.
4. Erros comuns de TLS em Flutter
Um erro crítico citado no artigo é:
HttpClient()
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
❌ Esse código desativa completamente a validação TLS e deve existir somente em ambientes locais controlados, nunca em produção.
Outros erros comuns:
- Não validar hostname
- Desabilitar TLS para “testes rápidos”
- Usar o mesmo código de debug em produção
- Confiar apenas no trust store do OS
5. Certificate Pinning
🔒
5.1 Conceito
Certificate Pinning limita explicitamente quais certificados ou chaves públicas o app aceita, ignorando CAs externas.
Modelo tradicional:
- Cliente confia em centenas de CAs
Modelo com pinning:
- Cliente confia apenas em certificados/chaves conhecidas
Mesmo que uma CA seja comprometida, o ataque falha.
5.2 Tipos de Pinning
| Tipo | Característica |
|---|---|
| Certificate Pinning | Fixa o certificado X.509 |
| Public Key Pinning | Fixa o hash da chave pública (SPKI) |
✔ O artigo recomenda Public Key Pinning, pois permite renovar certificados mantendo a mesma chave.
6. Extração da chave pública (SPKI)
6.1 Obter o certificado do servidor
openssl s_client -connect api.example.com:443 -showcerts
Salve o certificado em um arquivo, por exemplo cert.pem.
6.2 Extrair a chave pública
openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
6.3 Gerar o hash SHA-256 (Base64)
openssl pkey -pubin -outform der < pubkey.pem |
openssl dgst -sha256 -binary |
base64
📌 O valor resultante será usado como pin no aplicativo.
7. Implementação de Pinning em Flutter (Dart)
7.1 HttpClient com Public Key Pinning
import 'dart:io';
import 'dart:convert';
import 'package:crypto/crypto.dart';
class SecureHttpClient {
static const allowedPins = [
'sha256/BASE64_HASH_DA_CHAVE_PUBLICA',
];
static HttpClient create() {
final client = HttpClient();
client.badCertificateCallback =
(X509Certificate cert, String host, int port) {
final der = cert.der;
final hash = sha256.convert(der).bytes;
final fingerprint = 'sha256/${base64.encode(hash)}';
return allowedPins.contains(fingerprint);
};
return client;
}
}
Uso com o pacote http:
import 'package:http/io_client.dart';
final client = IOClient(SecureHttpClient.create());
final response = await client.get(
Uri.parse('https://api.example.com/data'),
);
Se o certificado não corresponder ao pin, a conexão falha imediatamente.
8. Reforço no nível de plataforma
8.1 Android — Network Security Config
📱
res/xml/network_security_config.xml
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2027-01-01">
<pin digest="SHA-256">
BASE64_HASH_DA_CHAVE_PUBLICA
</pin>
</pin-set>
</domain-config>
</network-security-config>
No AndroidManifest.xml:
<application
android:networkSecurityConfig="@xml/network_security_config"
... >
✔ Isso garante pinning no nível do sistema, mesmo fora do Dart.
8.2 iOS — App Transport Security (ATS)
🍎
O iOS já impõe TLS forte por padrão via ATS. No entanto:
- ATS não implementa pinning automaticamente
- Pinning exige validação customizada (como no Dart)
- Exceções ATS devem ser evitadas em produção
Exemplo de ATS seguro (sem exceções):
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
</dict>
9. Zero-Trust aplicado a Flutter
🧠
O artigo conecta pinning a uma abordagem Zero-Trust Mobile, baseada nos princípios:
- Nenhuma rede é confiável
- Nenhum dispositivo é confiável
- Toda comunicação deve ser validada
No Flutter, isso se traduz em:
- Certificate / Public Key Pinning
- Tokens de curta duração
- Secure Storage (Keychain / Keystore)
- Revalidação frequente de sessões
- Monitoramento de comportamento anômalo
- Detecção de root / jailbreak (quando aplicável)
O pinning é tratado como um pilar, não como solução isolada.
10. Limitações e cuidados operacionais
⚠️ Pontos reconhecidos no artigo:
- Pinning pode quebrar o app se certificados expirarem
- É necessário planejar rotação
- Usar múltiplos pins (primário + backup)
- Dispositivos comprometidos ainda podem burlar proteções
- A complexidade operacional aumenta
Por isso, pinning deve ser usado somente onde o risco justifica o custo.