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
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.
- 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
- You can install the package flutter_jailbreak_detection
- 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.
- Install the package flutter_dotenv
- 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
- Install package hive
- 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
- 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
- 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
- Please install package secure_application
- 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