dwyl / learn-flutter

🦋 Learn how to use Flutter to Build Cross-platform Native Mobile Apps
https://flutter.dev
GNU General Public License v2.0
87 stars 8 forks source link

Research: How to protect secrets in a `Flutter` App? 🔐 #82

Open nelsonic opened 1 year ago

nelsonic commented 1 year ago

Following on from the discussion in: https://github.com/dwyl/auth/issues/277#issuecomment-1441273288 We need to understand if it's possible to do "secrets" in a Flutter App ... 🔐 🤷‍♂️ If we are deploying a Flutter Web App e.g: https://dwylapp.fly.dev/ will any "secret" key that we include in it just be in the main.dart.js and thus readable by anyone. 💭

Opening this question as a research topic. 🔍 I would like a definitive answer to this. ✅ How do Banks that need to protect an API key do it? 🤷‍♀️ Do they have a multi-step handshake process for sharing 🤝 a session-based one-time key with their Flutter Web App ⏳ instead of including the an API key in their "bundle" (APK)? 💭

nelsonic commented 1 year ago

https://www.google.com/search?q=secrets+in+flutter

Went down a StackOverflow rabbit hole ...

LuchoTurtle commented 1 year ago

Flutter Web is just like any other frontend framework after being compiled and bundled to release. You of course already know that secrets should never be stored in the front end, they should always be server-side.

As you've mentioned in https://github.com/dwyl/auth/issues/277#issuecomment-1441273288, the reason the anon key works in Supabase's demo is because they have RLS (Row-Level Security) implemented, so users are not able to fetch whatever info they want. Otherwise, anon key would be terrible.

I'm aware that this issue stems from the auth discussion that you had in https://github.com/dwyl/auth/issues/277#issuecomment-1441273288 and https://github.com/dwyl/auth/issues/268 but systems like OIDC and Auth0 always use keys on server-side for reasons that you are already aware of.

I don't think there's a way to protect secrets on any Flutter app, as it's always vulnerable and "seeable" by anyone in the browser. https://www.reddit.com/r/Frontend/comments/l1mmkx/storing_api_keyssecrets/

nelsonic commented 1 year ago

@LuchoTurtle yeah, that's my understanding too. Glad we're on the same page. 👌 My goal for this issue was to verify my Null hypothesis: that we can't protect sensitive info in a Flutter App. I'm satisfied that this is the case and will document it accordingly. 📝

The RLS in Supabase (provided by Postgres) has to be enabled selectively, it's not enabled by default. https://supabase.com/docs/guides/auth/row-level-security It would be way better if it were system-wide out-of-the-box. Relying on Devs to implement it is a security nightmare in practice. Their anon key (which is another idea they copied from Firebase), is therefore just a way of identifying the app and not a security measure.

Having implemented various auth providers on previous front-end projects, the keys are all stored in the world-visible scripts, no server code needed ...

E.g. AWS Amplify most of the keys are optional: https://docs.amplify.aws/lib/auth/start/q/platform/js/#re-use-existing-authentication-resource And can be completely omitted for social login: https://docs.amplify.aws/lib/auth/social/q/platform/js/#full-sample

The best post I've found on this is by Flutter Google Developer Expert @bizz84: https://codewithandrea.com/articles/flutter-api-keys-dart-define-env-files/

Indeed, there is no way to perfectly conceal secrets in a Flutter App. 🙃 https://docs.flutter.dev/cookbook/networking/authenticated-requests

So we just have to follow our own best practice. 💭 We will continue to follow our .env file approach used in Elixir/Phoenix (server-side) Apps.