Securing Flutter Apps.

Mohammad Ezziedden
6 min readOct 31, 2021

--

In today’s digital landscape, many applications involve handling payments or storing sensitive personal information, thereby increasing the risk of security breaches and data exposure to malicious actors. This article will discuss the most effective practices for mitigating security vulnerabilities in Flutter apps, emphasizing the importance of implementing multiple layers of protection. While these measures significantly enhance security, it is important to acknowledge that no application can be made completely impervious to attacks.

Let’s Start

Protecting the communication Layer

Credit https://www.guardsquare.com/en/blog/iOS-SSL-certificate-pinning-bypassing

One of the primary targets for an attacker is the data being transmitted between your application and its server backend. Intercepting this data can expose vulnerabilities and sensitive information, making it crucial to ensure secure communication channels.

1- Employ strong encryption:

Utilize protocols such as SSL and TLS to ensure secure data transmission. These protocols are straightforward to implement in your code and provide robust security. For applications handling highly sensitive data, consider incorporating a VPN-like solution directly within your app for an added layer of protection.

2- Restrict network traffic:

Control network traffic by explicitly whitelisting your domain, which helps prevent connections to unsecured endpoints. In a Flutter app, this requires specific steps for each platform to ensure proper implementation:

android :

go to the android folder and create this file under

res/xml/network_security_config.xml

then copy this and add it to the created xml file:

<?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>

for ios:

add this to the info.plist file:

<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>

then replace YOURDOMAIN.com with your server domain.

Doing this will insure that your application will not be allowed to communicate with any other domain.

3- Certificate Pinning

SSL pinning solves the MITM (Man In The Middle) attack.

How ?

In simple language, you will get a server certificate file from the backend developer , and you will pin the certificate in every API call. So the HTTP client will take this certificate as a trustable one. Now if MITM happens and the app gets some bad certificate, the API calls will be broken due to a Handshake error.

so let’s implement this in flutter:

most probably the certificate extension will be “.cer” but this extension is not readable in flutter so we need to convert it to “.pem” by using this command .

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

Certificate is the file name you can use on your own.

after that add the certificate as an asset and add it to the pubspec.yaml.

Now using the Dio package we will manage all the requests in the app :

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; };

in this code we are reading the certificate from the assets and adding it as a trusted certificate to the http client of the dio instance.

Now when when using this dio instance to make any request to another server we will get a handshake error due to the invalid certificate for the server.

4-Make Authentication Bulletproof

Besides your app’s data streams, the next most common attack vector to eliminate is any weakness in its authentication methods.

so the two-factor authentication with your server is both necessary and worth implementing.

On top of that, you also need to pay attention to how you handle things like key exchanges. At a minimum, you should be using encryption to keep those transactions secure.

-Till now we had made our best to protect the transport layer with the server.

now let’s get into securing the app itself.

Protecting the Application .

Basic understanding of the Android app. Source — Pranay Airan.

1- Obfuscate Code

The compiled binaries and code of your apps can be reversed engineered. Some of the things that can be exposed include the strings, method and class names, and API keys. These data are either in their original form or in are in plain text.

-from the dart side what you can do is using the --obfuscate parameter when building your apk .

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

and from the native side you need to handle that by :

android

In your /android/app/build.gradle file, add the following:

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

Create a ProGuard configuration file in /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.** { *; }

With ProGuard, it does not only obfuscate your code but also helps you shrink the size of your Android apps.

iOS

If you are using Objective-C or Swift and building for iOS, the compiler strips the symbols and applies optimizations to your code, making it already harder for the motivated attacker to read the compiled output of your code.

There are also paid tools that help you obfuscate your code: iXGuard and Vermatrix.

2-Jailbroken and rooted devices

Jailbroken iOS and rooted Android devices have more privileges and may introduce malware to your user’s device that can circumvent the normal operations of the device.

flutter_jailbreak_detection is a package that helps you detect if your app is currently running on a jailbroken or rooted device,

It uses RootBeer on Android, and DTTJailbreakDetection on iOS.

and it is so easy to use :

import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart';

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

3- Secure user data

for storing sensitive user data you should never use the shared preferences or sqflite , cause it easy to open on any device, for that you need to encrypt the stored data, you can use flutter_secure_storage for that .

this package uses Keystore for Android and Keychains for iOS.

it is also worth setting up a periodic time for automatically cleaning the data cache that has been expired.

4. Use local authentication

Suppose the user phone has stolen and your application is installed on it and it has some payment information :)

to prevent any access to your app you should use Biometrics authentication by using this package .

5-Background Snapshot Prevention

When an app is backgrounded, the operating system takes a snapshot of the last visible state to present in the task switcher. Preventing account balances and payment details being captured by background snapshots is hence highly desired.

this could be solved by using this package

his plugin allow you to protect your application content from view on demand.

Summery

As a developer, your primary responsibility is to implement the best possible security measures to protect your application and its users. While absolute security cannot be guaranteed, the strategies discussed — such as employing strong encryption and restricting network traffic — significantly enhance the security posture of your Flutter app.

Additionally, it’s worth noting that the question, “How do you secure your Flutter app?” is one of the most common topics in job interviews for mobile application developers. I hope this article provides valuable insights and practical guidance to help you address this crucial aspect of app development.

cover photo credit : rawpixel.com — www.freepik.com

--

--