If you hang out in Flutter communities, you know we spend a lot of time arguing about state management. Bloc, Riverpod, Provider—pick your poison. But there's one topic we almost never talk about: what actually happens when a bad actor gets their hands on our compiled libapp.so?
I recently wanted to dive deep into mobile AppSec. The problem? Almost all the hands-on resources out there focus heavily on native Android (Java/Kotlin) or iOS (Swift). I wanted to see exactly how the OWASP Mobile Top 10 translates to the Flutter ecosystem, but I couldn't find a good playground to test things out.
So, I decided to build one myself. And I made it intentionally terrible. 😅
Meet the Damn Vulnerable Flutter App (DVFA).
It’s a FinTech-themed Flutter application purposely riddled with security flaws. I mapped the vulnerabilities directly to the OWASP Mobile Application Security Verification Standard (MASVS) so developers and security researchers can practice static analysis, intercept traffic, and reverse-engineer AOT binaries without setting up a massive environment from scratch.
Some of my favorite ways to break this app:
- AOT Reverse Engineering: (Challenge 7). The app exports an encrypted bank statement using the
encryptpackage (AES-CBC), but the AES key is statically managed in the Dart code. Your job? Extract thelibapp.sobinary, run it through tools likeblutter, and recover the hardcoded key. - Deep Link Hijacking: (Challenge 5). I registered a custom
dvfa://appscheme in the Android manifest. If you craft a malicious deep link, you can force the app to bypass user confirmation and automatically execute a fund transfer. - The "Oops" Data Leak: (Challenge 10). There is no explicitly vulnerable "bad code" here. Instead, I intentionally didn't implement a
WidgetsBindingObserver. Because the app doesn't detect when it goes to the background, the OS takes a clear screenshot of the financial dashboard for the App Switcher, leaking sensitive data.
I also threw in a Dockerized mock backend (built with Flask) so you can practice intercepting unencrypted HTTP traffic.
Try it out
If you want to test your AppSec skills, you can grab the compiled APK from the Releases tab for a blind black-box test, or clone the repo to read the source code:
👉 https://github.com/Schmiemandev/dvfa
What's next?
Building DVFA made me realize how insanely easy it is to misconfigure native manifests when you spend 99% of your time writing Dart. I'm currently hacking on a CLI tool that automatically scans Flutter CI/CD pipelines for these exact misconfigurations before the app gets compiled. I'll be open-sourcing that soon!
P.S. This is my very first article on DEV! Let me know what you think of DVFA, and if anyone actually manages to beat Challenge 7, drop a comment below, I'd love to see how you approached it!
Top comments (0)