Tips to Secure Flutter App

Tips to Secure Flutter App



Security on a software development it is important, for example the security data, data hacking, data leaks and so on.

Some of the typical risks of Flutter:

  • Flutter compiled directly into native code which makes developers think that security is not a major concern in Flutter applications.
  • Dart generate metadata that can easily provide insight into how the application works. Hackers perform static analysis that can compromise the security of Flutter applications and encourage malicious attempts.

This Article discuss some tips to protect your Application, so that it is sturdy from the hands of nosy (hackers).

Here are some tips for securing your app before releasing to Production.

1. Obfuscate Code


Since Flutter Binaries are natively compiled, the compiled Binaries and your application code can be reverse-engineered. Some of the things that can be exposed include strings, method and class names, and API keys.


Dart

For dart you can use command --obfuscate

  1. Android build .apk

flutter build apk --obfuscate --split-per-abi

    2. Android app bundle .abb

flutter build apk --obfuscate --split-per-abi



Android

You can use ProGuard. ProGuard has the base function in between :

  • Code shrinking (remove unused classes)
  • Obfuscation (protect code in decompile)
  • Optimization (help to resize Application)

Hare’s how to implement ProGuard.

  1. Open file android/app/build.gradle
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
useProguard true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86_64'
}
}
}

    2.  Create file for configuration ProGuard on /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.** { *; }


IOS

Because the Flutter IOS used Objective-C or Swift so it's been compiler and delete symbol then apply optimizations to your code, making it harder for hackers to read the compiled output of your code.



2. Flutter jailbreak detection


Some Apps run on Jailbroken (IOS) or Rooted (Android) devices. Jailbroken or rooted devices are vulnerable to malware or viruses. You can consider whether the user supports jailbroken or rooted devices.

Application

  1. You can install the package flutter_jailbreak_detection
  2. This is for detecting a device jailbroken or rooted.
import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart';

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

If jailbroken is true, it means the Device is jailbroken or rooted.



3. Secure API Keys


Protecting API keys using encryption can protect against hacking. Encrypts the API Key at run time, this will make it harder for hackers to read your API code.

  • 📌 Do not expose .env files to version control (GIT). 
  • 📌  Do not share .env files or any sensitive data on social media applications such as Whatsapp or Telegram.

Application

To configure the application with Global variables.

  1. Install the package flutter_dotenv
  2. Create new file .env into folder root.
API_KEY=SOME_VALUE
BASE_API=SOME_VALUE

    3. Register file .env into pubspec.yaml

assets:
- .env

    4. Load .env into main.dart

import 'package:flutter_dotenv/flutter_dotenv.dart';
Future main()async {
	await dotenv.load(fileName: ".env");
}

    5. Apply file .env 

dotenv.env['BASE_API'];

If you are using CI/CD for automatic release of applications, then you must create an Environment variable. Here's how to create an Environment in Codemagic.



4. Secure user data


User data information or PPI is the most important data that must be kept safe. If this user data is exposed transparently this is very dangerous for you.

📌  Do not save User data into plain text without encryption.

Application

  1. Install package hive
  2. Use box encryption on the package hive
import 'dart:convert';
import 'package:hive/hive.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
void main() async {
  const secureStorage = FlutterSecureStorage();
  // if key not exists return null
  final encryptionKey = await secureStorage.read(key: 'key');
  if (encryptionKey == null) {
    final key = Hive.generateSecureKey();
    await secureStorage.write(
      key: 'key',
      value: base64UrlEncode(key),
    );
  }
  final key = await secureStorage.read(key: 'key');
  final encryptionKey = base64Url.decode(key!);
  print('Encryption key: $encryptionKey');
  final encryptedBox= await Hive.openBox('vaultBox', encryptionCipher: HiveAesCipher(encryptionKey));
  encryptedBox.put('secret', 'Hive is cool');
  print(encryptedBox.get('secret'));
}


📌  The example above stores the encryption key using the flutter_secure_storage package, but you can use any package/method you want to securely store the encryption key when your application is closed.



5. Secure developer identity


Encrypting the development identity is a must, because otherwise it could allow hackers to infiltrate malware or viruses into your application.

Secret files that you must encrypt such as:

  • Keystore
  • Keystore.properties
  • Google service
  • File secret

 📌  Do not expose files to version control (GIT).

📌  Do not share any sensitive data files on social media applications such as whatsapp or Telegram.

Application

  1. The GPG for encrypting file sensitive, ex key.jks & keystore.properties
cd android; gpg --symmetric --cipher-algo AES256 android_keys.zip

    2. Open file .gitignore add name path :

# Ignore Android keys
key.jks
key.properties
service_account_key.json
android_keys.zip


6. Local Authentication 


Local authentication with biometrics such as fingerprints or facial recognition is useful for protecting applications from storing information such as payments or other important information. Local authentication also helps provide an extra layer of protection in case the device is stolen.

Application

  1. Install package local_auth


7. Background snapshots protection


Mobile devices have a task switcher feature that shows a snapshot of the app's recent status. Used to protect app content from viewing on demand.

Application

  1. Please install package secure_application
  2. Add a top-level Secure Application under MaterialApp()
SecureApplication(
        onNeedUnlock: (secure) => print(
            'need unlock maybe use biometric to confirm and then use sercure.unlock()'),
        child: MyAppContent(),
)


8. Stay up to Date


Keeping up to date with the latest Flutter SDKs, plugins, and packages is critical to improving the security of your Flutter app. If you think you've found an unresolved or unresolved issue in the Flutter repo, please report it to the Google Flutter Team.



Conclusion

Flutter is a cost-effective framework for building multiple platforms. Flutter applications are compiled directly into native code which makes developers think that security is not the main concern in Flutter applications.

Not all apps are 100% secure, hackers know how to reverse engineer binary can easily exploit security holes. Developing applications by paying attention to various security is the right step so that applications can develop continuously.



Reference

https://www.preemptive.com/obfuscation/

https://articles.wesionary.team/use-of-proguard-in-the-flutter-app-289cd7b31a18

https://docs.hivedb.dev/


Tips to Secure Flutter App
Nanang Prasetya 2 November, 2022
Share this post
Archive
Sign in to leave a comment
Flutter with SOLID Principle
SOLID is an acronym for the first five object-oriented design (OOD) principles by Robert C. Martin (also known as Uncle Bob).