Are compile-time variables secure in flutter?

733

This is precisely as insecure as any other approach.

Create project that uses the define

(If the define isn't used, it'll be stripped out, but obviously you want to use it.)

void main() {
  const String key = String.fromEnvironment('SECRET_KEY');
  print(key);
  runApp(const MyApp());
}

Build

I'm using "SEKRET" here rather than "123456" because there are a lot of "123456" strings in a normal APK and it could give a false positive.

flutter build apk --dart-define=APP_VERSION=0.1.2 --dart-define=SECRET_KEY=SEKRET

Open the APK

cd build/app/outputs/flutter-apk/
mkdir app
cd app
unzip ../app-release.apk

Look for secret strings

strings lib/x86_64/libapp.so | grep SEKRET
> SEKRET

This is no different than just hardcoding the string into the app. There is no benefit to "hiding" it in a define, and there's no way to really secure this. The best you can do is obfuscate and hope the attacker isn't highly motivated. Or invest in ongoing obfuscation and hardening improvements every time they crack your system. (This is very difficult and expensive, and there is, by its nature, no universal or permenant solution.)

You cannot hide an API key in a binary. You cannot hide an API key that an app uses in memory. You cannot reliably keep secrets from someone who controls the hardware the app runs on and is motivated to find those secrets.

Share:
733
FrancescoPenasa
Author by

FrancescoPenasa

Hi! I've got a Bachelor's degree and a Master's degree in Computer Science

Updated on January 01, 2023

Comments

  • FrancescoPenasa
    FrancescoPenasa over 1 year

    I've got some sensitive data (api secret key) to store in the app on the client-side, I know this is a bad practice to store this kind of information but there are not feasible alternatives for now, I'm already tampering the problems that could arise if such key is leaked, but I wish to know if encoding such key in the build during compile time is secure or not, in case of decompiling the code, even if obfuscated, is it more difficult to retrive a compile-time variable?

    Here an example of how I would use it

    flutter build apk --dart-define=APP_VERSION=0.1.2 --dart-define=SECRET_KEY=123456
    
    • Alejandro
      Alejandro over 2 years
      You can, at most, obfuscate it so that it doesn't show up in plain text. But if your program can read it (and it must, to use it), so can your attacker. Consider your key leaked as soon as you publish your program.
  • FrancescoPenasa
    FrancescoPenasa over 2 years
    Thank you very much for the answer
  • mLstudent33
    mLstudent33 over 2 years
    So basically there is no way to 100% protect these secrets from a motivated attacker? Meaning if I am using GCP, I would need to monitor my GCP account and watch for a hacker using compute resources after hacking my Flutter app and getting the key? Does GCP cover these types of losses?
  • Rob Napier
    Rob Napier over 2 years
    You generally shouldn't have your app talk directly to a third-party service. You should have it authenticate to your own server, and then have that server talk to your third-party service. Then you maintain control. No service is going to offer a blanket forgiveness of fraud (though many services will negotiate with you to forgive some of the costs of some single large fraud event). If you send your key out in your app, it can be used. And in any case, you absolutely must monitor any service you're paying for or responsible for.