Skip to main content

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

TipoCaracterística
Certificate PinningFixa o certificado X.509
Public Key PinningFixa 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.