Three Advanced Ways to Secure a Flutter App

Going beyond the basics to make your Flutter app as secure as possible.

Scott Hatfield
9 min readDec 18, 2022

It’s no secret that security can be a daunting, sometimes intimidating, topic, especially when it comes to mobile app development. The constantly evolving threat landscape and the increasing amount of sensitive information being accessed, stored, and transmitted through apps can make it feel overwhelming to keep up with the latest security best practices. However, it’s critical to remember that a security breach can not only harm your users and damage your reputation, but also it can also have severe financial consequences for your business. That’s why it’s essential to make security a top priority in your mobile app development efforts.

Flutter, like any modern mobile app development framework, includes a range of basic, and even not-so-basic, security features with which every Flutter developer should be familiar. Through federated plugins, more security features can easily be added to your app as well. These security features include code obfuscation, secure local storage, jailbreak/root detection, and support for secure network communication using SSL/TLS.

Those basic security features are extremely important but they should not be the end of your efforts to create the most secure mobile app possible. In this blog post, we’ll be discussing three advanced methods for increasing the security of your Flutter app, so you can have the confidence that your app is as secure as possible.

Obligatory 80’s computer hacking GIF.

Disable Application Backup (Android)

By default, Flutter apps built for Android can be backed up using the Android Debug Bridge (adb). This means that, using an Android phone with developer mode enabled, a local backup copy of your application can be created on a connected machine by simply running a single command in the terminal like this,

adb backup -f appbackup.ab com.example.counter_security_example

A prompt will then be presented on the phone and, assuming it is accepted, a full backup of the application will be available on the computer connected to the phone.

The phone will display a prompt to complete the backup.

So, what’s the problem with allowing a Flutter Android app to be backed up? The issue is that it is possible for a backed up Android app to be manipulated and restored onto a target device as a kind of cybersecurity attack. Here is a general overview of how this could be done:

  1. The attacker obtains a copy of the Android app that they want to manipulate and restore onto the target device using the adb command above.
  2. The attacker modifies the backed up app content by adding malicious code or altering its functionality in some way. This could involve adding code that allows the app to access sensitive information on the device, such as login credentials or personal data, or code that causes the app to perform certain actions that could cause harm to the user in some way.
  3. The attacker restores the modified app onto the target device by using the backup they created. This can be done by connecting the target device to a computer and using ADB or a third-party utility to restore the app.
  4. Once the modified app is installed on the target device, it can be used to perform a variety of malicious actions.

It is important to note that this type of attack requires a certain level of technical expertise and access to the target device. Nevertheless, allowing a Flutter Android app to be backed up can be a potential security concern.

Disallowing Android app backups

The good news is that this security concern is extremely easy to address with just a single parameter set in AndroidManifest.xml, which you can find in /android/app/src/main/.

Open AndroidManifest.xml

In the manifest, within the application tag, add the flag

android:allowBackup="false"

You may get a warning about allowBackup only being supported with API level 4 or higher. Since your target API level is at least level 16, which is the lowest version supported by Flutter, you can safely supress this warning by adding,

tools:targetApi="donut"

to the application tag alongside the allowBackup tag you just added. You can see this additional line in the screenshot above.

Once you have the backups disabled for the app, adb will no longer back up application data.

Prevent Screenshots from Exposing Sensitive Information

For most applications, there are screens on which sensitive information is exposed because it is necessary for the app to function. For example, if your app includes a login screen, you likely obscure the characters in the password field but you might have a button on the password field allowing a user to temporarily view the password. This is a useful feature because it allows users to double check their password entry to ensure they did not include a typo. You might also have a screen in your app allowing a user to update profile information, which may include physical address information, email addresses, phone numbers, or all kinds of other PII. Your app may include commerce functionality and, at some point, a customer may enter credit card information.

Even if you secure this information in every possible way while it is being transmitted to and from your app, and for any information being stored on the host device, the fact that this sensitive information is displayed on the screen can be a security concern by itself because this information could potentially be captured in a screenshot.

Screenshots can be taken by anyone with physical access to a device, and once taken, the screenshot can be shared with others or stored for later use. This can be a security risk if the screenshot contains sensitive information, such as login credentials, personal information, or confidential business information.

Much worse though is the possibility that a user’s screen could be recorded by a malicious program running on their device. Such a program could not only capture screenshots of an infected device without the user’s permissions, but also it could transmit the resulting files off the device.

Preventing Screenshots of Flutter Apps

The good news is that this security concern is easy to address. Using the screen_protector plugin, you can prevent screenshots from being taken of your app for all or just some of its screens.

On pages protected by the package, the visible content of the app is replaced by a blank colored screen or, depending on how you configure the plugin, a blurred overlay.

This is all you get, hackers! The screen_protector plugin makes screenshots capture only a blank screen.

A great way to use this plugin is to enable the screenshot protection only on screens that contain sensitive information while allowing screenshots to be taken of other pages. This way, your users’ sensitive information is protected from being exposed in screenshots, but they can still take screenshots of other parts of the app that do not include PII for sharing, customer support, recordkeeping or other purposes.

That said, preventing screenshots of your app should certainly not be the only way PII presented on the screen is protected. After all, there is still nothing stopping somebody from simply photographing the screen with a different device.

There is not much you can do to keep people from seeing sensitive information over your user’s shoulders so make sure your systems are protected in other ways too.

Scan for API Keys in Code

There was once a software developer named Jeb who was working on a new project for his company. One day, Jeb realized that he needed to include some API keys in his code so that he could test a new feature that he was working on.

Being in a rush, Jeb decided to just include the keys directly in the code running on his local machine. It takes time and attention, after all, to safely handle API keys. He didn’t think much of it at the time, as he planned to remove the keys later on once he was done testing.

However, Jeb forgot to remove the keys before pushing the code to the repository. And because the repository was public, anyone with access to it could see the keys. Jeb didn’t realize his mistake until it was too late. By that point, the keys had already been compromised and were being used by someone else to make unauthorized requests.

Most developers know that API keys should be handled with great care and that they should certainly not be included in public repositories like GitHub. Then again, numerous studies from universities and security researchers across the globe routinely find a truly sickening number of public repositories in which API keys are accidentally leaked.

Jeb according to DALL-E 2
DALL-E 2 prompt: “A professional portrait of Jeb, a software developer, studio lighting, wearing a graphic T-shirt of his favorite video game.”

So, as a safeguard to protect your API keys from accidentally being leaked, it can be useful to implement a API key scanner to make sure no keys, or other secrets like passwords, were inadvertently included in your codebase.

Scan for API Keys and Secrets using Gitleaks

One popular tool used to scan a repository for API keys and other information that should not be included is Gitleaks. The tool is extremely easy to use and provides an excellent safety measure for preventing scenarios like the one described for Jeb above.

Results from a scan using Gitleaks that detected an API key in a Git repository.

Depending on your operating system, there are different methods for installing Gitleaks that can be found on the Gitleaks GitHub page. Once you have the tool installed, there are two basic commands used to scan your codebase for potential leaks, one used to scan existing commits in the repository and one used to scan code that you are preparing to commit.

detect

gitleaks detect

The detect command is used to scan a repository for API keys or other sensitive pieces of information that are already included in the repository. The command scans through the codebase and delivers warnings if the tool finds any concerning pieces of information in any of the files. You can use this command to check if any of the work done on your repository to date has exposed API keys, passwords, or other information.

protect

gitleaks protect --staged

The protect command scans files with changes that have been staged for your repository (via the git add command) for potential leaks. This command is extremely useful for preventing leaks from getting committed in the first place.

Run Gitleaks Scans Before Commits

It is highly unlikely that an individual developer, and vanishingly unlikely that every member of a development team, would remember to run a Gitleaks scan before each commit. Fortunately, your Git repository can be set up to automatically scan for exposed API keys each time changes are committed. This way, commits will be rejected if they contain API keys or other sensitive bits of data.

  1. From the root directory of your project, open /.git/hooks . This folder contains, by default, a collection of sample pre-commit hooks, which are scrips that run after a user submits a git commit command but before the resulting changes are added to the version control.
Locate the hooks folder inside the potentially hidden .git directory.
  1. Locate the file called pre-commit.sample and rename it to pre-commit by removing the .sample extension.
Rename pre-commit.sample to just pre-commit.
  1. Open this file in your text editor of choice and replace its contents with
#!/bin/sh

exec gitleaks protect --staged

4. Now, each time a commit is made in the repository, gitleaks will check the staged files for API keys. If any API keys are found, the commit will not go through.

Thanks for reading and happy Fluttering!

--

--

Scott Hatfield

I like to take big, complicated projects, and break them down into simple steps that anybody can understand. https://toglefritz.com/