Segurança para Apps em Flutter
Published: 2021-11-22 22:41:34

Fala pessoal! Tudo certo por ai?

Então, o intuito principal dessa documentação é passar algumas informações e mostrar alguns métodos de segurança para os Apps em Flutter, visando diminuir consideravelmente as chances de um ataque a nossa aplicação.

Então bora!

Primeiramente devemos entender que hoje praticamente todas as aplicações mobile possuem pagamentos integrados ou informações importantes, como informações pessoais de usuários, com isso vamos abordar aqui alguns métodos para minimizar o risco de alguém malicioso tentar acessar essas informações.

###Protegendo a camada de comunicação
A primeira coisa que um hacker provavelmente irá olhar em nossa aplicação seria tentar interceptar alguma informação passada pelo app para o backend, vendo isso, temos algumas opções: 

###Encriptação dos dados: 
Você pode fazer isso usando protocolos como SSL e TLS, que são simples de adicionar ao seu código e muito difíceis de serem comprometidos.
Se você está lidando com dados particularmente sensíveis, você pode até ir um pouco mais longe e construir uma solução do tipo VPN diretamente em seu aplicativo.

Uma doc que pode ajudar: https://medium.com/surfstudio/ssl-pinning-in-flutter-apps-254e01e57965

###Restringindo o tráfego:
Uma maneira de restringir o tráfego de rede ou a conexão a um endpoint  é colocar seu domínio na lista de permissões explicitamente.
Para fazer isso no aplicativo flutter, precisamos seguir algumas etapas para cada plataforma:

***Android:*** 
Crie este arquivo dentro da pasta android: 

**res/xml/network_security_config.xml**

Então copie isso e jogue lá: 
```
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">YOURDOMAIN.com</domain>
        <trust-anchors>
            <certificates src="@raw/YOURCERTIFICATE"/>
        </trust-anchors>
    </domain-config>
</network-security-config>
```

***iOS:***

Adicione isso no arquivo **info.plist**:

```
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <false/>
  <key>NSExceptionDomains</key>
  <dict>
    <key>YOURDOMAIN.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>
  </dict>
</dict>
```

Apenas substitua o *YOURDOMAIN.com* pelo seu domínio!

###Aplicação de certificado: 
De forma simples, você pode obter um certificado para acesso ao servidor com o desenvolvedor backend e após isso poderia aplicar este certificado em cada chamada de API. Portanto, o cliente HTTP aceitará esse certificado como confiável.

E para implementar isso no Flutter: 

Provavelmente a extensão do certificado será “.cef”, porém ela não pode ser lida pelo Flutter, então temos que converte-la para “.pem” usando este comando: 

***openssl x509 -inform der -in Certificate.cer -out Certificate.pem***

Após isso, o certificado pode ser adicionado como uma asset e referenciado no pubspec.yaml.

Exemplo de requisição usando o Dio:
```
final dio = Dio(); 
ByteData bytes = await rootBundle.load('assets/Certificate.pem');  
(dio.httpClientAdapter as 
DefaultHttpClientAdapter).onHttpClientCreate  = (client) {      
SecurityContext sc = SecurityContext();      
sc.setTrustedCertificatesBytes(bytes.buffer.asUint8List());      
HttpClient httpClient = HttpClient(context: sc);      
return httpClient;    
};
```

###Autenticação a prova de balas!
Além dos fluxos de dados do seu aplicativo, o próximo vetor de ataque mais comum a ser eliminado é qualquer fraqueza em seus métodos de autenticação.
Portanto, a autenticação de dois fatores com seu servidor é necessária e vale a pena ser implementada.
Além disso, você também precisa prestar atenção em como lida com coisas como trocas de chaves. No mínimo, você deve usar criptografia para manter essas transações seguras.

- Agora que já vimos algumas formas de proteger a camada de transporte para o seu servidor, vamos ver algumas formas de proteger seu app por ele mesmo!

###Protegendo a aplicação
####Ofuscar código: 
Os binários compilados e o código de seus aplicativos podem sofrer engenharia reversa. Algumas das coisas que podem ser expostas incluem strings, nomes de métodos e classes e chaves de API. Esses dados estão em sua forma original ou em texto simples.

No lado do dart, podemos usar o seguinte comando com o parâmetro --obfuscate quando estivermos buildando a APK.

***flutter build appbundle --obfuscate --split-debug-info=/<directory>***

Já no lado nativo, você deve fazer algumas alterações: 

**Android:**

Dentro do */android/app/build.gradle* adicione o seguinte: 

```
android {
	...
	buildTypes {
		release {
			signingConfig signingConfigs.release
			minifyEnabled true
			useProguard true
			proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
		}
	}
}
```

Também crie uma configuração ProGuard em */android/app/proguard-rules.pro*:

```
# Flutter
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.**  { *; }
-keep class io.flutter.util.**  { *; }
-keep class io.flutter.view.**  { *; }
-keep class io.flutter.**  { *; }
-keep class io.flutter.plugins.**  { *; }
```

Com o ProGuard, ele não apenas ofusca seu código, mas também ajuda a reduzir o tamanho de seus aplicativos Android.

**iOS:** 

Se você estiver usando Objective-C ou Swift e compilando para iOS, o compilador remove os símbolos e aplica otimizações ao seu código, tornando já mais difícil para o invasor motivado ler a saída compilada do seu código.

Também existem ferramentas pagas que ajudam a ofuscar seu código: [iXGuard](https://www.guardsquare.com/ixguard) e [Vermatrix](https://www.verimatrix.com/).

###Jailbroken iOS e Android com root:
IOS desbloqueados e dispositivos Android com root possuem mais privilégios e pode introduzir malware no dispositivo de seu usuário que pode burlar as operações normais do dispositivo.

*flutter_jailbreak_detection* é uma package do Flutter que ajuda a detectar se o seu app está rodando nesses tipos de dispositivos.

Ele utiliza o [RootBeer](https://github.com/scottyab/rootbeer) no Android e o [DTTJailbreakDetection](https://github.com/thii/DTTJailbreakDetection) no iOS.

Para usá-lo: 
```
import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart';

bool jailbroken = await FlutterJailbreakDetection.jailbroken;
bool developerMode = await FlutterJailbreakDetection.developerMode; 
// android only.
```

###Assegurando dados dos usuários
Para guardar informações sensíveis dos usuários, não é bom ser usado o shared preferences ou sqflite, pois eles são bibliotecas “abertas” e podem ser acessadas em qualquer dispositivo, para encriptar os dados você pode usar o Flutter Secure Storage.
https://pub.dev/packages/flutter_secure_storage


###Usando autenticação local
Supomos que o dispositivo do usuário foi roubado com a sua aplicação instalada e dentro há informações sobre pagamentos! Puts, e agora?

Para isso, podemos usar métodos de autenticação local que irá prevenir o acesso indevido!

https://pub.dev/packages/local_auth


###Prevenção de capturas de informações de tela
Quando um aplicativo está em segundo plano, o sistema operacional deixa salva as informações do último estado visível para apresentar no alternador de tarefas. Evitar que os saldos das contas e detalhes de pagamento sejam capturados é altamente desejado.

E temos mais uma lib para ajudar!

https://pub.dev/packages/secure_application