DEV Community

Cover image for Is your Flutter application Secured? Best Practices for Developing and Deploying Secure Flutter Apps
Md. Mobin
Md. Mobin

Posted on

Is your Flutter application Secured? Best Practices for Developing and Deploying Secure Flutter Apps

I have been working on flutter for more than 2 years and I have seen many flutter developers who are not aware of the security issues in a flutter. So I have decided to write this article to make flutter developers aware of the security issues in flutter and how can you make your application secure so let's start.

meme 1

Securing API Keys

API stands for "Application Programming Interface". An API is a set of rules, protocols, and tools that define how software components should interact with each other. In other words, it is a way for different software applications to communicate and exchange information with each other.
we can secure API hard-coded either in dart or Native(Android, iOS, web)

  • API keys in Flutter code

for example, I have to use the API key in Dart code

void main(){
  String API_KEY="********"; //bad practice
}

Enter fullscreen mode Exit fullscreen mode

for avoiding this, we can use String.fromEnvironment() or .env file.

String.fromEnvironment() implementation

  • Load API in Dart code
  void main(){
    String? apiKey = String.fromEnvironment('API_KEY', defaultValue: null); //get api key from environment
    runApp(MyApp(apiKey: apiKey));
  }
Enter fullscreen mode Exit fullscreen mode
  • While compiling code pass the API key as an environment variable
  flutter build apk --dart-define==API_KEY=SECRET_KEY
Enter fullscreen mode Exit fullscreen mode

Load API key From .env file

for fetching API keys from the .env file use the following package:

flutter_dotenv

Note Do not forget to add the .env file in the .gitignore file

API keys in Native code

for example, Google Map API needs to be added to Android, iOS, and the web in respective files but APIs are not secured in AndroidManifest.xml, info.plist, and index.html.

Adding Google Map to flutter

Android:

  • Insert your API key in local.propertiesfile
   google.maps_api_key=SECRET_KEY

Enter fullscreen mode Exit fullscreen mode
  • Add local.properties file in .gitignore file
  • Now read the API key from local.properties file in build.gradle(app) file.
    def localProperties = new Properties()
    def localPropertiesFile = rootProject.file('local.properties')
    if (localPropertiesFile.exists()) {
        localPropertiesFile.withReader('UTF-8') { reader ->
            localProperties.load(reader)
        }
    }
    def googleMapsApiKey = localProperties.getProperty("google.maps_api_key")
    android {
        defaultConfig {
            manifestPlaceholders = [
                    googleMapsApiKey: googleMapsApiKey
            ]
        }
    }
Enter fullscreen mode Exit fullscreen mode
  • and add it to your AndroidManifest.xml file
    <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${googleMapsApiKey}" />
Enter fullscreen mode Exit fullscreen mode

For iOS:

  • Add your API key in ios/Flutter/Release.xcconfig file
     GOOGLE_MAPS_API_KEY=$(SECRET_KEY)
Enter fullscreen mode Exit fullscreen mode
  • Same as debug.xcconfig file

  • Now refer to these keys in info.plist file

   <key>google_maps_api_key</key>
    <string>$(GOOGLE_MAPS_API_KEY)</string>
Enter fullscreen mode Exit fullscreen mode
  • Now add it to your AppDelegate.swift file
    GMSServices.provideAPIKey("$(GOOGLE_MAPS_API_KEY)")
Enter fullscreen mode Exit fullscreen mode

For the web:

it is a little bit complicated but you can refer to the following link:

Dyanmic Html Elements- An approach to Flavours in Flutter Web by gonpalma

Encrypt Information and Storage

Encryption is the process of converting plain text data into an encoded format to ensure the confidentiality, integrity, and security of the data. In Flutter, encryption is often used to secure sensitive data such as passwords, user credentials, and financial information in mobile applications.

Flutter provides built-in support for encryption through the dart:crypto library, which includes various cryptographic functions such as hashing, symmetric encryption, and asymmetric encryption.

meme 2

  • Encryption local storage: Local storage is a place where we store the data locally on the device. So we should encrypt the data before storing it in the local storage. You can use the following packages to encrypt the data before storing it in the local storage.

  • Encryption Information: Sensitive data such as user credentials, payment information, and personal information should be encrypted both in transit and at rest. Flutter has built-in support for encryption through packages like crypto and encrypt.

Make Authentication Proof Your App

Authentication is the process of verifying the identity of a user. There are two types of authentication: client-side and server-side. Client-side authentication is done on the client side, and server-side authentication is done on the server side. Server-side authentication is more secure than client-side authentication. So we should use server-side authentication. You can use the following packages to implement server-side authentication as per your requirement.

As server-side authentication is more secure but it is not that local authentication is not secure. So we should use local authentication as well. For local authentication, you can use bio-metric, pins, or patterns.

image 2

local authentication is most used in banking applications or for any financial application.

Network Calls:

Network communication should be secured using HTTPS and SSL/TLS protocols to prevent data interception and tampering and to ensure data integrity. You can use the following packages to make network calls.

Note: try to ignore making network calls from a host starting with http:// and try to make network calls from a host starting with https://

is the Device Secure?

Any Banking application or Financial Application needs to be installed only on a safe device.

How can you check if a device is Rooted or Jail Breaked

You can use the following packages to check if the device is rooted or not.

Can your App could be Reverse engineered?

image 1

yeah, it is possible to reverse-engineer the source code. So we should obfuscate the source code. see here if you distribute debug build then it is easy to reverse-engineer the source code. So we should distribute the release build. But still, it is possible to reverse engineer the source code. So we should obfuscate the source code.

To obfuscate the source code you can use the following command

flutter build apk --obfuscate --split-debug-info=debug_info
Enter fullscreen mode Exit fullscreen mode

read more about obfuscation here

Control Background snapshots:

The following package secure_application, Secures app content visibility when users leave the app. It will hide content in the app switcher and display a frost barrier above locked content when the user gets backs.

Best Practices for Flutter App Development to make it more secure

  • Avoid using third-party libraries: As we know flutter has a lot of packages to make our work easy but we should avoid using third-party libraries as much as possible. Because we don't know what is going on inside the package. So it is better to use only trusted packages. before using any package we should check the package's popularity and the number of contributors. If the package has a lot of contributors and a lot of people are using it then it is safe to use it.

example

  • Overloading Permissions: overloading permissions is a technique to ask for more permissions than required. For example, if you want to access the camera then you should ask for camera permission only. But if you ask for storage permission also then it is called overloading permissions. So we should avoid overloading permissions as much as possible because it is a bad practice and users will not like it.

  • Avoid global variables or methods: for example, if you want to load a token from local storage then you should not store it in a global variable. Because if you store it in a global variable then it is easy to access it from anywhere. So it is better to store it in a local variable.

  • Perform security testing: Regularly perform security testing to identify potential vulnerabilities and ensure that security measures are effective. This can include penetration testing, code reviews, and vulnerability scanning.

  • Add Bug Bounty Program: A bug bounty program is a way to encourage ethical hackers to find and report vulnerabilities in your application. This can be a great way to find vulnerabilities that you may have missed. You can also offer a reward for finding vulnerabilities. This can help you find vulnerabilities before they are exploited by malicious hackers.

  • Use a Secure Coding Standard: A secure coding standard is a set of rules that developers must follow when writing code. This can help ensure that developers are writing secure code and that vulnerabilities are not introduced into the codebase. You can use a secure coding standard to ensure that developers are following best practices and that vulnerabilities are not introduced into the codebase.

  • For Production release use Pipeline: For production release use pipeline. The pipeline is a set of steps that are performed to build and release the application. This can include building the application, running tests, and deploying the application. This can help ensure that the application is secure and that vulnerabilities are not introduced into the application.
    Pipeline tools example GitHub actions, bitrise, circleci, Jenkins, etc.

GitHub action to build flutter app and distribute to using firebase app distribution read here.

If I forgot anything you can add it in the comment section, will add it later.

meme 3

Follow me:

Top comments (2)

Collapse
 
joukhar profile image
joukhar

i will be honest, this is absolutely a good article

Collapse
 
djsmk123 profile image
Md. Mobin

Thankyou