Securing Your Flutter Applications

Securing your Flutter applications can be a task if you do not know what you need to change and how it affects the overall build and yet this is the single most important thing when having an application in production.

Ryan Dsilva
Flutter Community
6 min readJul 5, 2022

--

Securing your Flutter applications should be something that every developer must take seriously as this directly affects the end-users of your application. Their data and all the communication happening to and from your application over the Internet can be exposed to all kinds of attacks and being aware of these risks and implementing steps to safeguard against them should be the responsibility of every developer.

P.S.: I recently spoke on this topic at Flutter Reboot, organized by Flutter Mumbai. 😄

Flutter + Security
Flutter + Security = ❤

One thing to note here, everything I mention in this article is subject to whether your app needs it. You have to decide whether this is critical to your application or not.

Firstly, let us start with some basic list items and then move on to more technical ones.

📦 Use trusted packages, Use fewer packages overall (if possible)

Most applications will depend on external packages for functionality or UI components and it is important to make sure that the packages used are developed by trusted developers, well maintained, and used by a considerable amount of people. The reason for that is that in case of an issue, it is spotted early because of the number of people using it. The pub.dev score and popularity should be a good starting point for this.

🔐 Always communicate over HTTPS

If your application communicates with external APIs and services, make sure the communication between your application and the remote server happens over HTTPS so that the data is encrypted during transit and no external hacker has easy access to the data during transit. Almost everything on the Internet has migrated to using HTTPS so this really should not be an option anymore but more of a default way of doing things.

HTTP having insecure connections vs HTTPS having encrypted connections
HTTP vs HTTPS

❌ Proper Error Handling and Messaging

Functions that have the possibility of throwing an exception should always be placed inside of a try-catch block so that you don’t present the user with unforeseen app crashes. In addition to that, it is also a good practice to show helpful error messages to the user BUT always refrain from showing the exact details of the error as this information might/can be used to find vulnerabilities easily.

Try Catch with Flutter

When Flutter applications are built for production release, if an error occurs, a grey screen is shown to the user which can be frustrating from a user’s point of view. Hence, showing a helpful error widget/screen might be a great way to ease the user experience.

Displaying a Custom Error Widget

📱Minimal Permissions

Make sure to use just enough app permissions that you require. If a particular permission is not essential to the functioning of your application, avoid using it. Using permissions without it being a necessity exposes the application to being under scrutiny from the stores. Moreover, the user’s privacy may be invaded if you do not use these permissions correctly. This is extremely serious as data and privacy policies globally get stricter by the day.

👨🏻‍💻 Always Encrypt Data

While storing data on the device such as tokens or any PII, this data should always be encrypted using the platform’s secure storage. A very useful package to facilitate this is flutter_secure_storage. This package is a simple key-value pair encrypted storage that is perfect for this use to store simple data types. Ideally, you should minimize the data stored on the device, but in cases where you need to store more data than just key-value pairs due to performance gains or any other reasons, hive can be very useful. Hive is NoSQL, on-device database written for Dart that is extremely performant and supports AES-256 encryption out-of-the-box.

Using Flutter Secure Storage

Moving on to more complex suggestions…

🔍 Code Obfuscation

Code Obfuscation is the practice of converting human-readable code into seemingly garbage reading code to make it harder for the attacker to understand if the application bundle is decompiled for reverse-engineering. The native platforms already do this by default on Flutter 2.0+ and for obfuscating Dart code we can include the --obfuscate flag along with the --split-debug-info flag with the location of the obfuscation symbols. These symbols can then be used to convert the obfuscated code back into readable code to debug issues if required.

flutter build appbundle --obfuscate --split-debug-info=./symbols/flutter build apk --obfuscate --split-debug-info=./symbols/flutter build ios --obfuscate --split-debug-info=./symbols/

🔑 SSL Pinning

SSL Pinning is a security measure that pins the identity of trustworthy certificates on mobile apps and blocks unknown documents from the suspicious servers. Applications with pinned SSL certificates rely on their stored certificates instead of relying on certificate authority stores licenses. With this technique, you can pin the SSL certificate host — list of trustful certificates to your application during development and further compare the server certificates against the list during runtime.

You can read more about SSL Pinning here: https://medium.com/@anuj.rai2489/ssl-pinning-254fa8ca2109

Diagrammatic view of how SSL pinning works
SSL Pinning

So to implement this we need:

  • The certificate in .pem format
  • Pre-request hook handler

To get the certificate in the required format, you first need to download the certificate from your web browser which will be in the .cer format, and then use the following command:

openssl x509 -in cert.cer -out cert.pem

Then use the verifyHandshake function in your pre-request hook handler in your http library of choice.

SSL Pinning

🤖 Network Security Config (Android Only)

This is the native configuration to enable the app to communicate only with allowed domains enforcing HTTPS connection. The security_config.xml file should have entries for all the domains your application needs to communicate with. The includeSubdomains parameter specifies whether you want to include all the subdomains of your main domain. If you choose not to include all subdomains, you can individually specify each subdomain in the domain list. The certificate for each domain needs to the added to the following location in the .pem format: android/app/src/main/res/raw and the security_config.xml file sits in the android/app/src/main/res/xml folder.

Security Config — Android

🍎 NSAppTransportSecurity (iOS only)

This is the native configuration to enable the app to communicate only with allowed domains enforcing HTTPS connection. The NSExceptionDomains key should have entries for all the domains your application needs to communicate with. The NSIncludesSubdomains key specifies whether you want to include all the subdomains of your main domain. If you choose not to include all subdomains, you can individually specify each subdomain in the domain list. The following snippet should be appended to the Info.plist file under ios/Runner.

NSAppTransportSecurity Config — iOS

📱Jailbreak & Root Detection

Based on the type of application, you may want to restrict usage on rooted/jailbroken devices. Not allowing your application to run on rooted/jailbroken devices will prevent hackers from accessing your app data on the device and other activities that may compromise your application. For this, we’ll use the flutter_jailbreak_detection package.

Root / Jailbreak Detection

Thank you so much for reading this article. If you found this helpful, please don’t forget to clap and share this article with as many people as you can 😄

Thank You!
Thank You!

You can follow me on my socials:

GitHub (@RyanDsilva): https://github.com/RyanDsilva

Medium (@ryan.dsilva): https://medium.com/@ryan.dsilva

LinkedIn (@ryan-dsilva): https://www.linkedin.com/in/ryan-dsilva/

Twitter (@ryan_dsilva98): https://twitter.com/ryan_dsilva98

Follow Flutter Community on Twitter: https://www.twitter.com/FlutterComm

--

--

Ryan Dsilva
Flutter Community

Full Stack TypeScript/JavaScript Developer | Flutter | Deep Learning | Grad Student — Purdue University